]> diplodocus.org Git - nmh/commitdiff
Merge branch 'fix-post-bcc'
authorKen Hornstein <kenh@pobox.com>
Tue, 1 Aug 2017 17:22:36 +0000 (13:22 -0400)
committerKen Hornstein <kenh@pobox.com>
Tue, 1 Aug 2017 17:22:36 +0000 (13:22 -0400)
This branch fixes bug #51098; the lack of alias expansion on a From line
when doing a Bcc.  Admittedly, this is rather an obscure bug, and AFAICT
it never worked in any version of MH or nmh, but it is fixed now.

21 files changed:
Makefile.am
configure.ac
h/icalendar.h
h/mh.h
h/utils.h
mts/smtp/smtp.c
sbr/dtime.c
sbr/icalendar.l
sbr/icalparse.y
sbr/m_getfld.c
sbr/m_name.c
sbr/netsec.c
sbr/utils.c
test/inc/test-eom-align
test/mhical/test-mhical
test/repl/test-convert
uip/forw.c
uip/inc.c
uip/mhbuildsbr.c
uip/mhical.c
uip/mhshowsbr.c

index ae7b98c..4f6627e 100644 (file)
@@ -166,9 +166,7 @@ TESTS = \
     test/whom/test-whom \
     test/cleanup ## The "cleanup" test should always be last.
 
-XFAIL_TESTS = \
-    test/inc/test-eom-align \
-    #
+XFAIL_TESTS =
 
 check_SCRIPTS = test/common.sh
 
index 8651dd1..1d42bf5 100644 (file)
@@ -555,7 +555,6 @@ AS_IF([test "x$with_oauth" = xyes && test "x$HAVE_CURL_H" = x],
 dnl ----------------
 dnl CHECK FLEX FIXUP
 dnl ----------------
-dnl BUG: This stops $(LFLAGS) working as it comes after $(AM_FLAGS).
 dnl Use AM_LFLAGS make variable setting to work around bugs in flex
 dnl 2.5.36-37 that cause signed/unsigned mismatch,
 dnl http://sourceforge.net/p/flex/bugs/140/
@@ -563,13 +562,15 @@ dnl 2.6.1 bug: https://github.com/westes/flex/issues/97
 AS_IF([test "$LEX" = flex],
       [AS_CASE([`$LEX -V`],
                [flex\ 2.5.35], [AM_LFLAGS=\
-'; sed "s/     int n;/ size_t n;/" $@ >$@.tmp && mv -f $@.tmp $@'],
+'; sed "s/     int n;/ size_t n;/" $@ >$@.tmp && mv -f $@.tmp $@;'],
                [flex\ 2.5.3[[67]]], [AM_LFLAGS=\
-'; sed "s/\(   \)int i;/\1yy_size_t i;/" $@ >$@.tmp && mv -f $@.tmp $@'],
+'; sed "s/\(   \)int i;/\1yy_size_t i;/" $@ >$@.tmp && mv -f $@.tmp $@;'],
                [flex\ 2.6.0], [AM_LFLAGS=\
-'; sed "s/, num_to_read/, (size_t) num_to_read/" $@ >$@.tmp && mv -f $@.tmp $@'],
+'; sed "s/, num_to_read/, (size_t) num_to_read/" $@ >$@.tmp && mv -f $@.tmp $@;'],
                [flex\ 2.6.1], [AM_LFLAGS=\
-'; sed '\''/\<int num_to_read\>/s/int/size_t/; s/\<yy_size_t i\>/int i/'\'' $@ >$@.tmp && mv -f $@.tmp $@'])
+'; sed '\''/\<int num_to_read\>/s/int/size_t/; \
+                s/\<yy_size_t i\>/int i/; \
+                s/int n; \\/yy_size_t n; \\/'\'' $@ >$@.tmp && mv -f $@.tmp $@;'])
        AC_SUBST([AM_LFLAGS])])
 
 dnl ------------------
index 9f8546c..be7244e 100644 (file)
@@ -39,6 +39,7 @@ typedef struct contentline {
     char *input_line;          /* The (unfolded) input line. */
     size_t input_line_len;     /* Amount of text stored in input_line. */
     size_t input_line_size;    /* Size of allocated input_line. */
+    charstring_t unexpected;   /* Accumulate unexpected characters in input. */
 
     cr_indicator cr_before_lf; /* To support CR before LF.  If the first
                                   line of the input has a CR before its LF,
@@ -92,12 +93,13 @@ extern int icaldebug;
 int icalparse (void);
 extern vevent vevents;
 int icallex (void);
+extern int parser_status;
 
 /* And this is for the icalendar scanner. */
 extern YYSTYPE icallval;
 
 /*
- * For directing the scanner to use a files other than stdin/stdout.
+ * For directing the scanner to use files other than stdin/stdout.
  * These don't use the accessors provided by modern flex because
  * flex 2.5.4 doesn't supply them.
  */
diff --git a/h/mh.h b/h/mh.h
index 6b7dec6..1ff275b 100644 (file)
--- a/h/mh.h
+++ b/h/mh.h
@@ -376,14 +376,6 @@ struct msgs {
 
 typedef struct m_getfld_state *m_getfld_state_t;
 
-/*
- * Maildrop styles
- */
-#define        MS_DEFAULT      0       /* default (one msg per file) */
-#define        MS_UNKNOWN      1       /* type not known yet         */
-#define        MS_MBOX         2       /* Unix-style "from" lines    */
-#define        MS_MMDF         3       /* string MMDF_DELIM          */
-
 #define        NOUSE   0               /* draft being re-used */
 
 #define TFOLDER 0              /* path() given a +folder */
index 0c6c734..297746d 100644 (file)
--- a/h/utils.h
+++ b/h/utils.h
@@ -106,6 +106,19 @@ int contains8bit(const char *start, const char *end);
  */
 int scan_input (int fd, int *eightbit);
 
+/*
+ * Returns string representation of int, in static memory.
+ */
+char *m_str(int value);
+
+/*
+ * Returns string representation of an int, in static memory.  If width
+ * == 0, does not limit the width.  If width > 0 and value will not fit
+ * in field of that size, including any negative sign but excluding
+ * terminating null, then returns "?".
+ */
+char *m_strn(int value, unsigned int width);
+
 /*
  * program initialization
  *
index 0ef19b0..7808e1a 100644 (file)
@@ -870,7 +870,8 @@ char *
 rp_string (int code)
 {
     char *text;
-    static char buffer[BUFSIZ];
+    /* The additional space is to avoid warning from gcc -Wformat-truncation. */
+    static char buffer[BUFSIZ + 19];
 
     switch (sm_reply.code != NOTOK ? code : NOTOK) {
        case RP_AOK:
index 481cfe6..56d874e 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <h/mh.h>   /* for snprintf() */
 #include <h/nmh.h>
+#include <h/utils.h>
 #include <h/tws.h>
 #include <time.h>
 
@@ -183,10 +184,10 @@ dctime (struct tws *tw)
     if (!tw)
        return NULL;
 
-    snprintf (buffer, sizeof(buffer), "%.3s %.3s %02d %02d:%02d:%02d %.4d\n",
+    snprintf (buffer, sizeof(buffer), "%.3s %.3s %02d %02d:%02d:%02d %s\n",
            tw_dotw[tw->tw_wday], tw_moty[tw->tw_mon], tw->tw_mday,
            tw->tw_hour, tw->tw_min, tw->tw_sec,
-           tw->tw_year < 100 ? tw->tw_year + 1900 : tw->tw_year);
+           m_strn(tw->tw_year < 100 ? tw->tw_year + 1900 : tw->tw_year, 4));
 
     return buffer;
 }
@@ -284,24 +285,23 @@ dasctime (struct tws *tw, int flags)
  * return the string representation of the numeric offset.
  */
 
-char *
-dtimezone (int offset, int flags)
+char *dtimezone(int offset, int flags)
 {
-    int hours, mins;
-    static char buffer[10];
-
-    if (offset < 0) {
-       mins = -((-offset) % 60);
-       hours = -((-offset) / 60);
-    } else {
-       mins = offset % 60;
-       hours = offset / 60;
-    }
+    static char buffer[sizeof "+3579139459"]; /* 2,147,483,648 / 60 = 35,791,394 */
+    bool pos;
+    unsigned os, hours, mins;
+
+    pos = offset >= 0;
+    os = pos ? offset : ~offset + 1; /* abs(3) undefined on INT_MIN. */
+    hours = os / 60;
+    mins = os % 60;
+
+    if (flags & TW_DST) /* Shift towards +infinity. */
+        hours += pos ? 1 : -1;
+
+    snprintf(buffer, sizeof(buffer), "%c%02u%02u",
+        pos ? '+' : '-', hours, mins);
 
-    if (flags & TW_DST)
-       hours++;
-    snprintf (buffer, sizeof(buffer), "%s%02d%02d",
-               offset < 0 ? "-" : "+", abs (hours), abs (mins));
     return buffer;
 }
 
index 11006e7..8b0721b 100644 (file)
@@ -257,7 +257,15 @@ folded-value         {VALUE-CHAR}*({fold}{VALUE-CHAR}*)+
 
 . {
     /* By default, flex will just pass unmatched text.  Catch it instead. */
-    inform("unexpected input: |%s|\n", icaltext);
+    contentline *clines = vevents.last->contentlines;
+    contentline *cline;
+
+    if (clines  &&  (cline = clines->last)) {
+        if (cline->unexpected == NULL) {
+            cline->unexpected = charstring_create (0);
+        }
+        charstring_append_cstring (cline->unexpected, icaltext);
+    }
 }
 
 <INITIAL>
index dc58d4a..88edb0c 100644 (file)
@@ -38,7 +38,7 @@
 #include "h/utils.h"
 
 static char *append (contentline *, const char *, const size_t);
-static void new_input_line (contentline **);
+static void new_content_line (contentline **);
 static void new_vevent (vevent *);
 static void free_param_names (param_list *);
 static void free_param_values (value_list *);
@@ -62,7 +62,7 @@ contentline_list
     /* contentline = name *(";" param ) ":" value CRLF */
 contentline
     : ICAL_NAME {
-          new_input_line (&vevents.last->contentlines);
+          new_content_line (&vevents.last->contentlines);
           append (vevents.last->contentlines->last, $1, strlen ($1));
           vevents.last->contentlines->last->name = $1;
       } ICAL_COLON {
@@ -87,7 +87,7 @@ contentline
           }
       }
     | ICAL_NAME {
-          new_input_line (&vevents.last->contentlines);
+          new_content_line (&vevents.last->contentlines);
           append (vevents.last->contentlines->last, $1, strlen ($1));
           vevents.last->contentlines->last->name = $1;
       } param_list ICAL_COLON {
@@ -211,7 +211,7 @@ append (contentline *cline, const char *src, const size_t src_len) {
 }
 
 static void
-new_input_line (contentline **cline) {
+new_content_line (contentline **cline) {
     contentline *new_node;
 
     NEW0(new_node);
@@ -296,6 +296,7 @@ free_contentlines (contentline *root) {
         }
         free (i->value);
         free (i->input_line);
+        charstring_free (i->unexpected);
         next = i->next;
         free (i);
     }
@@ -326,11 +327,27 @@ free_param_values (value_list *v) {
 
 static int
 icalerror (const char *error) {
+    contentline *c;
+    charstring_t context = NULL;
+
+    /* Find last chunk of unexpected text. */
+    for (c = vevents.last->contentlines; c; c = c->next) {
+        if (c->unexpected) {
+            context = c->unexpected;
+        }
+    }
+
     if (! strcmp ("syntax error, unexpected $end, expecting ICAL_NAME",
                   error)) {
         /* Empty input: produce no output. */
     } else {
-        adios (NULL, "%s", error);
+        if (context) {
+            inform ("%s after \"%s\"", error, charstring_buffer (context));
+        } else {
+            inform ("%s", error);
+        }
+        parser_status = -1;
+        return -1;
     }
 
     return 0;  /* The return value isn't used anyway. */
index e82a2ff..d74f386 100644 (file)
@@ -205,6 +205,14 @@ static int m_Eom (m_getfld_state_t);
 #define eom(c,s)       (s->msg_style != MS_DEFAULT && \
                         ((c) == *s->msg_delim && m_Eom(s)))
 
+/*
+ * Maildrop styles
+ */
+#define        MS_DEFAULT      0       /* default (one msg per file) */
+#define        MS_UNKNOWN      1       /* type not known yet         */
+#define        MS_MBOX         2       /* Unix-style "from" lines    */
+#define        MS_MMDF         3       /* string MMDF_DELIM          */
+
 /* This replaces the old approach, with its direct access to stdio
  * internals.  It uses one fread() to load a buffer that we manage.
  *
@@ -874,6 +882,7 @@ m_Eom (m_getfld_state_t s)
     int i;
     char text[MAX_DELIMITER_SIZE];
     char *cp;
+    int adjust = 1;
 
     for (i = 0, cp = text; i < s->edelimlen; ++i, ++cp) {
        int c2;
@@ -882,22 +891,31 @@ m_Eom (m_getfld_state_t s)
            *cp = '\0';
            break;
        }
-        *cp = c2;
+       *cp = c2;
     }
 
     if (i != s->edelimlen  ||
         strncmp (text, (char *)s->edelim, s->edelimlen)) {
-       if (i == 0 && s->msg_style == MS_MBOX)
+       if (i == 0 && s->msg_style == MS_MBOX) {
            /* the final newline in the (brain damaged) unix-format
             * maildrop is part of the delimiter - delete it.
             */
            return 1;
+       }
+
+       if (i <= 2  &&  s->msg_style == MS_MBOX  &&
+           i != s->edelimlen  &&  ! strncmp(text, s->fdelim, i)) {
+           /* If all or part of fdelim appeared at the end of the file,
+              back up even more so that the bytes are included in the
+              message. */
+           adjust = 2;
+       }
 
        /* Did not find delimiter, so restore the read position.
           Note that on input, a character had already been read
           with Getc().  It will be unget by m_getfld () on return. */
-       s->readpos -= s->bytes_read - 1;
-       s->bytes_read = 1;
+       s->readpos -= s->bytes_read - adjust;
+       s->bytes_read = adjust;
        return 0;
     }
 
index a4b49af..9bc8c0b 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <limits.h>
 #include <h/mh.h>
+#include <h/utils.h>
 
 #define STR(s) #s
 #define SIZE(n) (sizeof STR(n)) /* Includes NUL. */
 char *
 m_name (int num)
 {
-    static char name[SIZE(INT_MAX)];
+    if (num <= 0) return "?";
 
-    if (num <= 0)
-       return "?";
-
-    snprintf(name, sizeof name, "%d", num);
-
-    return name;
+    return m_strn(num, SIZE(INT_MAX));
 }
index dd75bfd..ab05cf8 100644 (file)
@@ -1631,7 +1631,7 @@ netsec_negotiate_tls(netsec_context *nsc, char **errstr)
            if (BIO_get_ssl(nsc->ssl_io, &ssl) < 1) {
                netsec_err(errstr, "Certificate verification failed, but "
                           "cannot retrieve SSL handle: %s",
-                          ERR_error_string(ERR_get_error(), NULL));
+                           ERR_error_string(errcode, NULL));
            } else {
                netsec_err(errstr, "Server certificate verification failed: %s",
                           X509_verify_cert_error_string(
@@ -1639,7 +1639,7 @@ netsec_negotiate_tls(netsec_context *nsc, char **errstr)
            }
        } else {
            netsec_err(errstr, "TLS negotiation failed: %s",
-                      ERR_error_string(errcode, NULL));
+                       ERR_error_string(errcode, NULL));
        }
 
        /*
index 8281b4f..90f36bd 100644 (file)
@@ -11,6 +11,7 @@
 #include "m_mktemp.h"
 #include "makedir.h"
 #include <fcntl.h>
+#include <limits.h>
 
 extern char *mhdocdir;
 
@@ -572,3 +573,32 @@ scan_input (int fd, int *eightbit) {
 
     return state == NOTOK  ?  NOTOK  :  OK;
 }
+
+
+/*
+ * Convert an int to a char string.
+ */
+char *
+m_str(int value) {
+    return m_strn(value, 0);
+}
+
+
+/*
+ * Convert an int to a char string, of limited width if > 0.
+ */
+#define STR(s) #s
+/* SIZE(n) includes NUL.  n must just be digits, not an equation. */
+#define SIZE(n) (sizeof STR(n))
+
+char *
+m_strn(int value, unsigned int width) {
+    /* Need to include space for negative sign.  But don't use INT_MIN
+       because it could be a macro that would fool SIZE(n). */
+    static char buffer[SIZE(-INT_MAX)];
+    const int num_chars = snprintf(buffer, sizeof buffer, "%d", value);
+
+    return num_chars > 0  &&  (width == 0 || (unsigned int) num_chars <= width)
+        ? buffer
+        : "?";
+}
index 8539b5d..5c81d74 100755 (executable)
@@ -95,6 +95,7 @@ makembox_B () {
 # Do a single test with message one's body of size sz.
 do_one_test_A () {
   SZ=$1
+  printf '%5s A\r' $SZ
   makembox_A "$MH_TEST_DIR/eom-align.mbox" $SZ
   $VALGRIND inc -silent -file "$MH_TEST_DIR/eom-align.mbox"
   # We know the messages should be 11 and 12 in inbox
@@ -112,6 +113,7 @@ do_one_test_A () {
 # Do a test type B
 do_one_test_B () {
   SZ=$1
+  printf '%5s B\r' $SZ
   makembox_B "$MH_TEST_DIR/eom-align.mbox" $SZ
   $VALGRIND inc -silent -file "$MH_TEST_DIR/eom-align.mbox"
   # We know the message should be 11 in the inbox
@@ -128,9 +130,20 @@ arith_eval $STDIO_BUFSZ - 16; START=$arith_val
 arith_eval $STDIO_BUFSZ + $HDRSZ + $FROMLINESZ + 32; FINISH=$arith_val
 [ -t 1 ]  &&  echo \
 "Testing inc of files with various alignments of eom marker with buffer size..."
+
+#### Trouble spots for the particular input, with BUFSZ of 8192:
+for sz in 3146 3147 7241 7242 7243 11338 11339 15433 15434 15435; do
+  do_one_test_A $sz
+done
+
+# Also 155, 174, 175, but they're too small for makembox_B to handle.
+for sz in 684 4074 4097 4148 4610 4611 5121 5122 6654 6655 8170 \
+          8193 8244 8364 12266 12289 12340 16362 16385 16436; do
+  do_one_test_B $sz
+done
+
 i="$START"
 while test $i -le $FINISH; do
-  printf '  %s' $i
   do_one_test_A $i
   do_one_test_B $i
   i=`expr $i + 1`
index f6d75af..930c35f 100755 (executable)
@@ -841,5 +841,38 @@ END:VCALENDAR" | TZ=UTC mhical >"$actual"
 check "$expected" "$actual"
 
 
+# check invalid line folding
+start_test "invalid line folding"
+
+cat >"$expected" <<'EOF'
+Summary: test
+Description: this file does not end with a newline
+At: Sun, 14 May 2017 13:00 +0000
+To: Sun, 14 May 2017 14:00
+EOF
+
+cat >"$expected_err" <<'EOF'
+mhical: syntax error, unexpected ICAL_COMMA, expecting ICAL_COLON after " this line is not folded"
+EOF
+
+set +e
+printf %s \
+"BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//TDP v3.0//EN
+BEGIN:VEVENT
+DTSTAMP:20170514T122300Z
+DTSTART:20170514T130000Z
+DTEND:20170514T140000Z
+SUMMARY:test
+DESCRIPTION:this file does not end with a newline
+and this line is not folded,
+END:VEVENT
+END:VCALENDAR" | TZ=UTC mhical >"$actual" 2>"$actual_err"
+set -e
+check "$expected" "$actual"
+check "$expected_err" "$actual_err"
+
+
 finish_test
 exit $failed
index f2792a6..0cbc131 100755 (executable)
@@ -74,10 +74,10 @@ mhbuild "$actual"
 check "$actual" "$expected"
 
 
-# check that text is not quoted-printable encoded
+# check that text is quoted-printable encoded due to long text line
 # This tests the setting of reply_ct->c_reqencoding and
 # (*text_plain_ct)->c_reqencoding in expand_pseudoheader().
-start_test "don't encode text as quoted-printable"
+start_test "encode text as quoted-printable due to long text line"
 cat >"$expected" <<'EOF'
 From: recipient@example.com
 To: sender@example.com
@@ -88,10 +88,12 @@ Comments: In-reply-to sender@example.com
    message dated "Thu, 11 Dec 2014 08:19:02 -0600."
 MIME-Version: 1.0
 Content-Type: text/plain; charset="US-ASCII"
+Content-Transfer-Encoding: quoted-printable
 
 sender@example.com writes:
 
-> This is a very, very, very, very, very, very, very, very, very, very, very, long line.
+> This is a very, very, very, very, very, very, very, very, very, very, ve=
+ry, long line.
 EOF
 
 cat >`mhpath new` <<'EOF'
index 77b2d0d..cb02554 100644 (file)
@@ -111,7 +111,7 @@ main (int argc, char **argv)
     char *dmsg = NULL, *digest = NULL, *ed = NULL;
     char *file = NULL, *filter = NULL, *folder = NULL, *fwdmsg = NULL;
     char *from = NULL, *to = NULL, *cc = NULL, *subject = NULL, *fcc = NULL;
-    char *form = NULL, buf[BUFSIZ], value[10];
+    char *form = NULL, buf[BUFSIZ];
     char **argp, **arguments;
     struct stat st;
     struct msgs_array msgs = { 0, 0, NULL };
@@ -454,11 +454,9 @@ try_it_again:
 
        if (digest) {
            snprintf (buf, sizeof(buf), IFORMAT, digest);
-           snprintf (value, sizeof(value), "%d", issue);
-           context_replace (buf, mh_xstrdup(value));
+           context_replace (buf, mh_xstrdup(m_str(issue)));
            snprintf (buf, sizeof(buf), VFORMAT, digest);
-           snprintf (value, sizeof(value), "%d", volume);
-           context_replace (buf, mh_xstrdup(value));
+           context_replace (buf, mh_xstrdup(m_str(volume)));
        }
 
        context_replace (pfolder, folder);      /* update current folder   */
index f388839..0890f83 100644 (file)
--- a/uip/inc.c
+++ b/uip/inc.c
@@ -623,7 +623,7 @@ main (int argc, char **argv)
 
            case SCNFAT:
                trnflag = 0;
-               noisy++;
+               noisy = true;
                /* advise (cp, "unable to read"); already advised */
                break;
 
@@ -764,7 +764,7 @@ main (int argc, char **argv)
 
            case SCNFAT:
                trnflag = 0;
-               noisy++;
+               noisy = true;
                /* advise (cp, "unable to read"); already advised */
                break;
 
index e209616..e34dd97 100644 (file)
@@ -2205,7 +2205,6 @@ expand_pseudoheader (CT ct, CT *text_plain_ct, struct multipart *m,
     struct str2init *s2i;
     CT reply_ct;
     struct part *part;
-    int eightbit = 0;
     int status;
 
     type_p = getcpy (type);
@@ -2220,15 +2219,13 @@ expand_pseudoheader (CT ct, CT *text_plain_ct, struct multipart *m,
     free (type_p);
 
     if (! (convert)) {
-        /* No mhbuild-convert- entry in mhn.defaults or profile
-           for type. */
+        /* No mhbuild-convert- entry in mhn.defaults or profile for type. */
         return;
     }
     /* reply_file is used to pass the output of the convert. */
     reply_file = getcpy (m_mktemp2 (NULL, invo_name, NULL, NULL));
     convert_command =
-        concat (convert, " ", FENDNULL(argstring), " >", reply_file,
-                NULL);
+        concat (convert, " ", FENDNULL(argstring), " >", reply_file, NULL);
 
     /* Convert here . . . */
     ct->c_storeproc = mh_xstrdup(convert_command);
@@ -2251,19 +2248,6 @@ expand_pseudoheader (CT ct, CT *text_plain_ct, struct multipart *m,
         return;
     }
 
-    /* For text content only, see if it is 8-bit text. */
-    if (reply_ct->c_type == CT_TEXT) {
-        int fd;
-
-        if ((fd = open (reply_file, O_RDONLY)) == NOTOK  ||
-            scan_input (fd, &eightbit) == NOTOK) {
-            free (reply_file);
-            inform("failed to read %s, continuing...", reply_file);
-            return;
-        } 
-        (void) close (fd);
-    }
-
     /* This sets reply_ct->c_ctparams, and reply_ct->c_termproc if the
        charset can't be handled natively. */
     for (s2i = str2cts; s2i->si_key; s2i++) {
@@ -2276,45 +2260,22 @@ expand_pseudoheader (CT ct, CT *text_plain_ct, struct multipart *m,
         (*reply_ct->c_ctinitfnx)(reply_ct);
     }
 
-    if ((cp =
-         get_param (reply_ct->c_ctinfo.ci_first_pm, "charset", '?', 1))) {
+    if ((cp = get_param (reply_ct->c_ctinfo.ci_first_pm, "charset", '?', 1))) {
         /* The reply Content-Type had the charset. */
         charset = cp;
     } else {
         set_charset (reply_ct, -1);
         charset = get_param (reply_ct->c_ctinfo.ci_first_pm, "charset", '?', 1);
-        if (reply_ct->c_reqencoding == CE_UNKNOWN  &&
-            reply_ct->c_type == CT_TEXT) {
-            /* Assume that 8bit is sufficient (for text).  In other words,
-               don't allow it to be encoded as quoted printable if lines
-               are too long.  This also sidesteps the check for whether
-               it needs to be encoded as binary; instead, it relies on
-               the applicable mhbuild-convert-text directive to ensure
-               that the resultant text is not binary. */
-            reply_ct->c_reqencoding = eightbit  ?  CE_8BIT  :  CE_7BIT;
-        }
     }
 
     /* Concatenate text/plain parts. */
-    if (reply_ct->c_type == CT_TEXT  &&
-        reply_ct->c_subtype == TEXT_PLAIN) {
+    if (reply_ct->c_type == CT_TEXT  &&  reply_ct->c_subtype == TEXT_PLAIN) {
         if (! *text_plain_ct  &&  m->mp_parts  &&  m->mp_parts->mp_part  &&
             m->mp_parts->mp_part->c_type == CT_TEXT  &&
             m->mp_parts->mp_part->c_subtype == TEXT_PLAIN) {
             *text_plain_ct = m->mp_parts->mp_part;
-            /* Make sure that the charset is set in the text/plain
-               part. */
+            /* Make sure that the charset is set in the text/plain part. */
             set_charset (*text_plain_ct, -1);
-            if ((*text_plain_ct)->c_reqencoding == CE_UNKNOWN) {
-                /* Assume that 8bit is sufficient (for text).  In other words,
-                   don't allow it to be encoded as quoted printable if lines
-                   are too long.  This also sidesteps the check for whether
-                   it needs to be encoded as binary; instead, it relies on
-                   the applicable mhbuild-convert-text directive to ensure
-                   that the resultant text is not binary. */
-                (*text_plain_ct)->c_reqencoding =
-                    eightbit  ?  CE_8BIT  :  CE_7BIT;
-            }
         }
 
         if (*text_plain_ct) {
index 67ba90d..650b982 100644 (file)
@@ -56,6 +56,7 @@ DEFINE_SWITCH_ARRAY(MHICAL, switches);
 #undef X
 
 vevent vevents = { NULL, NULL, NULL};
+int parser_status = 0;
 
 int
 main (int argc, char *argv[]) {
@@ -236,7 +237,7 @@ main (int argc, char *argv[]) {
         free (outfile);
     }
 
-    return 0;
+    return parser_status;
 }
 
 /*
index 11ec02b..6f8a978 100644 (file)
@@ -499,11 +499,15 @@ show_content_aux2 (CT ct, int alternate, char *cracked, char *buffer,
 
        default: {
            int status;
+            char *display_prog = vecp > 2  &&  vec[2][0] != '\0'
+                /* Copy the real display program name.  This relies on the
+                   specific construction of vec[] by argsplit(). */
+                ?  vec[2]
+                :  NULL;
 
-           arglist_free(file, vec);
-
-           pidcheck ((status = pidXwait (child_id, NULL)));
+            pidcheck ((status = pidXwait (child_id, display_prog)));
 
+            arglist_free(file, vec);
            if (fd != NOTOK)
                (*ct->c_ceclosefnx) (ct);
            return (alternate ? OK : status);