From 2433122c20baccb10b70b49c04c6b0497b5b3b60 Mon Sep 17 00:00:00 2001 From: markus schnalke Date: Sat, 14 Apr 2012 17:35:18 +0200 Subject: [PATCH] No more mhshow-charset-* but instead automatic invocation of iconv(1). Unless there is an mhshow-show-* rule, text/plain content types are automatically piped through iconv(1) if their charset is foreign. For mhshow-show-* rules, there's a new %c escape, which expands to the foreign charset. The contents of the files, referenced by %f/%F are still in foreign encoding. One might want to use `iconv -f %c %f | mycommand' for custom mhshow-show-* rules. We depend on iconv(1) now! But this may change to dependence on iconv(3), soon. This field is inconsistent and not at all finished, yet. --- h/mhparse.h | 2 +- uip/mhfree.c | 4 ++-- uip/mhlistsbr.c | 2 +- uip/mhparse.c | 21 +++----------------- uip/mhshowsbr.c | 59 +++++++++++++++++++------------------------------------ 5 files changed, 27 insertions(+), 61 deletions(-) diff --git a/h/mhparse.h b/h/mhparse.h index 6778654..cca26e9 100644 --- a/h/mhparse.h +++ b/h/mhparse.h @@ -94,6 +94,7 @@ struct Content { struct CTinfo c_ctinfo; /* parsed elements of Content-Type */ int c_type; /* internal flag for content type */ int c_subtype; /* internal flag for content subtype */ + char *c_charset; /* charset string */ /* Content-Transfer-Encoding info (decoded contents) */ CE c_cefile; /* structure holding decoded content */ @@ -112,7 +113,6 @@ struct Content { int c_rfc934; /* rfc934 compatibility flag */ char *c_showproc; /* default, if not in profile */ - char *c_termproc; /* for charset madness... */ char *c_storeproc; /* overrides profile entry, if any */ char *c_storage; /* write contents (file) */ diff --git a/uip/mhfree.c b/uip/mhfree.c index 5fe5b2d..bf3382c 100644 --- a/uip/mhfree.c +++ b/uip/mhfree.c @@ -78,10 +78,10 @@ free_content(CT ct) break; } + if (ct->c_charset) + free(ct->c_charset); if (ct->c_showproc) free(ct->c_showproc); - if (ct->c_termproc) - free(ct->c_termproc); if (ct->c_storeproc) free(ct->c_storeproc); diff --git a/uip/mhlistsbr.c b/uip/mhlistsbr.c index 1777cf4..5dee115 100644 --- a/uip/mhlistsbr.c +++ b/uip/mhlistsbr.c @@ -255,8 +255,8 @@ list_debug(CT ct) ct->c_type, ct->c_subtype, (unsigned int)(unsigned long) ct->c_ctparams); + fprintf(stderr, " charset \"%s\"\n", empty(ct->c_charset)); fprintf(stderr, " showproc \"%s\"\n", empty(ct->c_showproc)); - fprintf(stderr, " termproc \"%s\"\n", empty(ct->c_termproc)); fprintf(stderr, " storeproc \"%s\"\n", empty(ct->c_storeproc)); /* print transfer encoding information */ diff --git a/uip/mhparse.c b/uip/mhparse.c index cf264c6..dc8e380 100644 --- a/uip/mhparse.c +++ b/uip/mhparse.c @@ -963,9 +963,7 @@ InitGeneric(CT ct) static int InitText(CT ct) { - char buffer[BUFSIZ]; - char *chset = NULL; - char **ap, **ep, *cp; + char **ap, **ep; struct k2v *kv; struct text *t; CI ci = &ct->c_ctinfo; @@ -992,10 +990,11 @@ InitText(CT ct) /* check if content specified a character set */ if (*ap) { + /* store its name */ + ct->c_charset = getcpy(norm_charmap(*ep)); /* match character set or set to CHARSET_UNKNOWN */ for (kv = Charset; kv->kv_key; kv++) { if (!mh_strcasecmp(*ep, kv->kv_key)) { - chset = *ep; break; } } @@ -1004,20 +1003,6 @@ InitText(CT ct) t->tx_charset = CHARSET_UNSPECIFIED; } - /* - ** If we can not handle character set natively, - ** then check profile for string to modify the - ** terminal or display method. - ** - ** termproc is for mhshow, though mhlist -debug prints it, too. - */ - if (chset != NULL && !check_charset(chset, strlen(chset))) { - snprintf(buffer, sizeof(buffer), "%s-charset-%s", - invo_name, chset); - if ((cp = context_find(buffer))) - ct->c_termproc = getcpy(cp); - } - return OK; } diff --git a/uip/mhshowsbr.c b/uip/mhshowsbr.c index adb0da7..fe3afc4 100644 --- a/uip/mhshowsbr.c +++ b/uip/mhshowsbr.c @@ -335,6 +335,13 @@ show_content_aux(CT ct, int alternate, char *cp, char *cracked) } break; + case 'c': + /* insert charset */ + if (ct->c_charset) { + strncpy(bp, ct->c_charset, buflen); + } + break; + case 'd': /* insert content description */ if (ct->c_descr) { @@ -446,25 +453,6 @@ raw: } } - if (buflen <= 0 || (ct->c_termproc && - (size_t)buflen <= strlen(ct->c_termproc))) { - /* - ** content_error would provide a more useful error message - ** here, except that if we got overrun, it probably would - ** too. - */ - fprintf(stderr, "Buffer overflow constructing show command!\n"); - return NOTOK; - } - - /* use charset string to modify display method */ - if (ct->c_termproc) { - char term[BUFSIZ]; - - strncpy(term, buffer, sizeof(term)); - snprintf(buffer, sizeof(buffer), ct->c_termproc, term); - } - got_command: return show_content_aux2(ct, alternate, cracked, buffer, fd, xlist, xstdin, xtty); @@ -573,7 +561,12 @@ show_text(CT ct, int alternate) ** if it is not a text part of a multipart/alternative */ if (!alternate || ct->c_subtype == TEXT_PLAIN) { - snprintf(buffer, sizeof(buffer), "%%p%s '%%F'", defaultpager); + if (!check_charset(ct->c_charset, strlen(ct->c_charset))) { + snprintf(buffer, sizeof(buffer), "%%liconv -f '%s'", + ct->c_charset); + } else { + snprintf(buffer, sizeof(buffer), "%%lcat"); + } cp = (ct->c_showproc = getcpy(buffer)); return show_content_aux(ct, alternate, cp, NULL); } @@ -768,6 +761,13 @@ show_multi_aux(CT ct, int alternate, char *cp) } break; + case 'c': + /* insert charset */ + if (ct->c_charset) { + strncpy(bp, ct->c_charset, buflen); + } + break; + case 'd': /* insert content description */ if (ct->c_descr) { @@ -887,25 +887,6 @@ raw: } } - if (buflen <= 0 || (ct->c_termproc && - (size_t)buflen <= strlen(ct->c_termproc))) { - /* - ** content_error would provide a more useful error message - ** here, except that if we got overrun, it probably would - ** too. - */ - fprintf(stderr, "Buffer overflow constructing show command!\n"); - return NOTOK; - } - - /* use charset string to modify display method */ - if (ct->c_termproc) { - char term[BUFSIZ]; - - strncpy(term, buffer, sizeof(term)); - snprintf(buffer, sizeof(buffer), ct->c_termproc, term); - } - return show_content_aux2(ct, alternate, NULL, buffer, NOTOK, xlist, 0, xtty); } -- 1.7.10.4