]> diplodocus.org Git - nmh/commitdiff
Added -[no]textcharset switches to mhshow(1). These only apply if
authorDavid Levine <levinedl@acm.org>
Sun, 9 Feb 2014 15:58:00 +0000 (09:58 -0600)
committerDavid Levine <levinedl@acm.org>
Sun, 9 Feb 2014 15:58:00 +0000 (09:58 -0600)
nmh was configured with iconv(3) support.  If -textcharset is not
used, mhshow will convert, if necessary, the charset of text/plain
content to match the user's locale setting.

Makefile.am
docs/pending-release-notes
man/mhshow.man
test/mhshow/test-charset
test/mhshow/test-textcharset [new file with mode: 0755]
uip/mhshow.c
uip/mhshowsbr.c

index 5bc612c85a2e71f4ecda274785d911bfc30dee28..73fd9ced4eb181f16293b7fab9ee754b3b18037c 100644 (file)
@@ -72,7 +72,7 @@ TESTS = test/ali/test-ali test/anno/test-anno \
        test/mhfixmsg/test-mhfixmsg \
        test/mhlist/test-mhlist test/mhmail/test-mhmail \
        test/mhparam/test-mhparam test/mhpath/test-mhpath \
        test/mhfixmsg/test-mhfixmsg \
        test/mhlist/test-mhlist test/mhmail/test-mhmail \
        test/mhparam/test-mhparam test/mhpath/test-mhpath \
-       test/mhshow/test-charset \
+       test/mhshow/test-charset test/mhshow/test-textcharset \
        test/mhshow/test-cte-binary test/mhshow/test-qp \
        test/mhshow/test-subpart test/mhshow/test-msg-buffer-boundaries \
        test/mhstore/test-mhstore test/new/test-basic \
        test/mhshow/test-cte-binary test/mhshow/test-qp \
        test/mhshow/test-subpart test/mhshow/test-msg-buffer-boundaries \
        test/mhstore/test-mhstore test/new/test-basic \
index 35bc26a3558a7029902bcd1c1b4f46ac4731637e..dc764f1eac9da3f80c61b86b72aad9ab05a863d5 100644 (file)
@@ -74,6 +74,10 @@ NEW FEATURES
   Nmh-Attachment).
 - The default Content-Transfer-Encoding for text parts is now 8bit.
 - mhbuild(1) now supports a selectable Content-Transfer-Encoding
   Nmh-Attachment).
 - The default Content-Transfer-Encoding for text parts is now 8bit.
 - mhbuild(1) now supports a selectable Content-Transfer-Encoding
+- Added -[no]textcharset switches to mhshow(1).  These only apply if
+  nmh was configured with iconv(3) support.  If -textcharset is not
+  used, mhshow will convert, if necessary, the charset of text/plain
+  content to match the user's locale setting.
 
 -----------------
 OBSOLETE FEATURES
 
 -----------------
 OBSOLETE FEATURES
index 9cc44c1b83597c52f68c3a011b7ae79de6f509f7..baafe7e541a43c3602a7f1ff62ea9e261e78cc51 100644 (file)
@@ -1,4 +1,4 @@
-.TH MHSHOW %manext1% "May 4, 2013" "%nmhversion%"
+.TH MHSHOW %manext1% "February 9, 2014" "%nmhversion%"
 .\"
 .\" %nmhwarning%
 .\"
 .\"
 .\" %nmhwarning%
 .\"
@@ -22,6 +22,9 @@ mhshow \- display MIME messages
 .RB [ \-pause " | " \-nopause ]
 .RB [ \-form
 .IR formfile ]
 .RB [ \-pause " | " \-nopause ]
 .RB [ \-form
 .IR formfile ]
+.RB [ \-textcharset
+.I charset
+.RB "| " \-notextcharset ]
 .RB [ \-rcache
 .IR policy ]
 .RB [ \-wcache
 .RB [ \-rcache
 .IR policy ]
 .RB [ \-wcache
@@ -321,6 +324,20 @@ switch can be given to tell
 .B mhshow
 to never display parts in parallel.
 .SS "Showing Alternate Character Sets"
 .B mhshow
 to never display parts in parallel.
 .SS "Showing Alternate Character Sets"
+If
+.B mhshow
+was built with
+.IR iconv (3),
+then all text/plain parts of the message(s) will be displayed
+using the character set of the current locale.  This character
+set can be overridden with the
+.B \-textcharset
+switch.  To convert text parts other than text/plain, or if
+.B mhshow
+was not built with
+.IR iconv ,
+an external program can be used, as described next.
+.PP
 Because a content of type text might be in a non-ASCII character
 set, when
 .B mhshow
 Because a content of type text might be in a non-ASCII character
 set, when
 .B mhshow
@@ -379,29 +396,24 @@ needed beforehand.
 Note that many pagers strip off the high-order bit or have problems
 displaying text with the high-order bit set.  However, the pager
 .B less
 Note that many pagers strip off the high-order bit or have problems
 displaying text with the high-order bit set.  However, the pager
 .B less
-has support for single-octet character sets.  The source
-to
-.B less
-is available on many ftp sites carrying free software.
-In order to view messages sent in the ISO-8859-1 character set using
+has support for single-octet character sets.  For example, messages
+encoded in the ISO-8859-1 character set can be view using
 .BR less ,
 .BR less ,
-.PP
-put these lines in your
-.I \&.login
-file:
+with these environment variable settings:
 .PP
 .RS 5
 .nf
 .PP
 .RS 5
 .nf
-setenv LESSCHARSET latin1
-setenv LESS "-f"
+.ta \w'%F  'u
+LESSCHARSET latin1
+LESS        -f
 .fi
 .RE
 .PP
 .fi
 .RE
 .PP
-The first line tells
+The first setting tells
 .B less
 to use the ISO-8859-1 definition for
 determining whether a character is \*(lqnormal\*(rq, \*(lqcontrol\*(lq,
 .B less
 to use the ISO-8859-1 definition for
 determining whether a character is \*(lqnormal\*(rq, \*(lqcontrol\*(lq,
-or \*(lqbinary\*(rq.  The second line tells
+or \*(lqbinary\*(rq.  The second setting tells
 .B less
 not to warn you
 if it encounters a file that has non-ASCII characters.  Then, simply
 .B less
 not to warn you
 if it encounters a file that has non-ASCII characters.  Then, simply
@@ -599,6 +611,7 @@ is checked.
 ^moreproc:~^Default program to display text/plain content
 .fi
 .SH "SEE ALSO"
 ^moreproc:~^Default program to display text/plain content
 .fi
 .SH "SEE ALSO"
+.IR iconv (3),
 .IR mhbuild (1),
 .IR mhl (1),
 .IR mhlist (1),
 .IR mhbuild (1),
 .IR mhl (1),
 .IR mhlist (1),
@@ -611,6 +624,7 @@ is checked.
 .RB ` \-nocheck '
 .RB ` \-form\ mhl.headers '
 .RB ` \-pause '
 .RB ` \-nocheck '
 .RB ` \-form\ mhl.headers '
 .RB ` \-pause '
+.RB ` \-notextcharset '
 .RB ` \-rcache\ ask '
 .RB ` \-noserialonly '
 .RB ` \-wcache\ ask '
 .RB ` \-rcache\ ask '
 .RB ` \-noserialonly '
 .RB ` \-wcache\ ask '
index 83363da86de2f1fd6ca091744f53d073dd0df087..d0d8028bdca5ee0919723749f5d86c45730df00a 100755 (executable)
@@ -16,6 +16,8 @@ fi
 
 setup_test
 
 
 setup_test
 
+LC_ALL=en_US.UTF-8; export LC_ALL
+
 expected=$MH_TEST_DIR/$$.expected
 actual=$MH_TEST_DIR/$$.actual
 
 expected=$MH_TEST_DIR/$$.expected
 actual=$MH_TEST_DIR/$$.actual
 
diff --git a/test/mhshow/test-textcharset b/test/mhshow/test-textcharset
new file mode 100755 (executable)
index 0000000..b80802f
--- /dev/null
@@ -0,0 +1,75 @@
+#!/bin/sh
+##########################################################
+#
+# Test display of text/plain parts with charset conversion
+#
+##########################################################
+
+set -e
+
+if test -z "${MH_OBJ_DIR}"; then
+    srcdir=`dirname "$0"`/../..
+    MH_OBJ_DIR=`cd "$srcdir" && pwd`; export MH_OBJ_DIR
+fi
+
+. "$MH_OBJ_DIR/test/common.sh"
+
+setup_test
+
+if test "$ICONV_ENABLED" -eq 0; then
+  echo "$0: skipping test-textcharset because nmh was built without iconv"
+  exit 0
+fi
+
+expected="$MH_TEST_DIR"/$$.expected
+actual="$MH_TEST_DIR"/$$.actual
+
+msgfile=`mhpath new`
+cat >"$msgfile" <<EOF
+From: foo@example.edu
+To: bar@example.edu
+Subject: test display with charset conversion
+MIME-Version: 1.0
+Content-Type: text/plain; charset=windows-1252
+Content-Transfer-Encoding: quoted-printable
+Date: Sun, 18 Dec 2005 00:52:39 +0100
+
+4 =F7 2 =3D 2
+EOF
+
+# Check -notextcharset.
+cat >"$expected" <<EOF
+Date:    Sun, 18 Dec 2005 00:52:39 +0100
+To:      bar@example.edu
+From:    foo@example.edu
+Subject: test display with charset conversion
+
+MIME-Version: 1.0
+
+EOF
+
+run_prog mhshow -textcharset UTF-8 -notextcharset -nopause last >"$actual" 2>&1
+check "$expected" "$actual"
+
+# Check -textcharset.
+cat >"$expected" <<EOF
+Date:    Sun, 18 Dec 2005 00:52:39 +0100
+To:      bar@example.edu
+From:    foo@example.edu
+Subject: test display with charset conversion
+
+MIME-Version: 1.0
+
+part       text/plain                  10
+4 รท 2 = 2
+EOF
+
+run_prog mhshow -textcharset UTF-8 -nopause last >"$actual" 2>&1
+check "$expected" "$actual" 'keep first'
+
+# Check use of user's locale.
+LC_ALL=en_US.UTF-8; export LC_ALL
+run_prog mhshow -nopause last >"$actual" 2>&1
+check "$expected" "$actual"
+
+exit $failed
index f83236b7433e1f063ef77ce29aa6efb6121c86b1..eb6ea16b89e93ff1b617edb0ef316309c8e681a2 100644 (file)
@@ -31,6 +31,8 @@
     X("form formfile", 0, FORMSW) \
     X("part number", 0, PARTSW) \
     X("type content", 0, TYPESW) \
     X("form formfile", 0, FORMSW) \
     X("part number", 0, PARTSW) \
     X("type content", 0, TYPESW) \
+    X("textcharset", 0, TEXTCHARSETSW) \
+    X("notextcharset", 0, NTEXTCHARSETSW) \
     X("rcache policy", 0, RCACHESW) \
     X("wcache policy", 0, WCACHESW) \
     X("version", 0, VERSIONSW) \
     X("rcache policy", 0, RCACHESW) \
     X("wcache policy", 0, WCACHESW) \
     X("version", 0, VERSIONSW) \
@@ -66,6 +68,7 @@ extern char *cache_private;
 extern int pausesw;
 extern int serialsw;
 extern char *progsw;
 extern int pausesw;
 extern int serialsw;
 extern char *progsw;
+extern char *display_charset;
 extern int nomore;     /* flags for moreproc/header display */
 extern char *formsw;
 
 extern int nomore;     /* flags for moreproc/header display */
 extern char *formsw;
 
@@ -200,6 +203,16 @@ do_cache:
                types[ntype++] = cp;
                continue;
 
                types[ntype++] = cp;
                continue;
 
+           case TEXTCHARSETSW:
+               if (!(cp = *argp++) || *cp == '-')
+                   adios (NULL, "missing argument to %s", argp[-2]);
+               display_charset = cp;
+               continue;
+
+            case NTEXTCHARSETSW:
+                display_charset = NULL;
+                continue;
+
            case FILESW:
                if (!(cp = *argp++) || (*cp == '-' && cp[1]))
                    adios (NULL, "missing argument to %s", argp[-2]);
            case FILESW:
                if (!(cp = *argp++) || (*cp == '-' && cp[1]))
                    adios (NULL, "missing argument to %s", argp[-2]);
index 8c595d76f67a9336c5e7cb3919ea17fdfd5ab45b..fa449772c09d97140e6459f7c3338334f1dcc885 100644 (file)
@@ -28,6 +28,7 @@ int serialsw = 0;
 int nolist   = 0;
 
 char *progsw = NULL;
 int nolist   = 0;
 
 char *progsw = NULL;
+char *display_charset = NULL;
 
 /* flags for moreproc/header display */
 int nomore   = 0;
 
 /* flags for moreproc/header display */
 int nomore   = 0;
@@ -69,6 +70,7 @@ static int show_multi_aux (CT, int, int, char *);
 static int show_message_rfc822 (CT, int, int);
 static int show_partial (CT, int, int);
 static int show_external (CT, int, int);
 static int show_message_rfc822 (CT, int, int);
 static int show_partial (CT, int, int);
 static int show_external (CT, int, int);
+static int convert_content_charset (CT, char **);
 static void intrser (int);
 
 
 static void intrser (int);
 
 
@@ -314,6 +316,17 @@ show_content_aux (CT ct, int serial, int alternate, char *cp, char *cracked)
     if (ct->c_showproc && !strcmp (ct->c_showproc, "true"))
        return (alternate ? DONE : OK);
 
     if (ct->c_showproc && !strcmp (ct->c_showproc, "true"))
        return (alternate ? DONE : OK);
 
+    if (! strcmp(invo_name, "mhshow")  &&
+        ct->c_type == CT_TEXT  &&  ct->c_subtype == TEXT_PLAIN) {
+        /* This has to be done after calling c_ceopenfnx, so
+           unfortunately the type checks are necessary without
+           some code rearrangement.  And to make this really ugly,
+           only do it in mhshow, not mhfixmsg, mhn, or mhstore. */
+        if (convert_content_charset (ct, &file) != OK) {
+            return NOTOK;
+        }
+    }
+
     xlist  = 0;
     xpause = 0;
     xstdin = 0;
     xlist  = 0;
     xpause = 0;
     xstdin = 0;
@@ -1217,6 +1230,39 @@ convert_charset (CT ct, char *dest_charset, int *message_mods) {
 }
 
 
 }
 
 
+static int
+convert_content_charset (CT ct, char **file) {
+    /* Convert character set if needed and if built with iconv. */
+#ifdef HAVE_ICONV
+    if (display_charset == NULL) {
+        /* The user did not specify a display charset, so use
+           current setting and see if the content will need to be
+           converted. */
+        char *charset = content_charset (ct);
+
+        if (! check_charset (charset, strlen (charset))) {
+            int unused = 0;
+            if (convert_charset (ct, get_charset (), &unused) == 0) {
+                *file = ct->c_cefile.ce_file;
+            } else {
+                return NOTOK;
+            }
+        }
+    } else {
+        /* The user requested display with a specific charset. */
+        int unused = 0;
+        if (convert_charset (ct, display_charset, &unused) == 0) {
+            *file = ct->c_cefile.ce_file;
+        } else {
+            return NOTOK;
+        }
+    }
+#endif /* ! HAVE_ICONV */
+
+    return OK;
+}
+
+
 static void
 intrser (int i)
 {
 static void
 intrser (int i)
 {