rohrpost

A commandline mail client to change the world as we see it.
git clone git://r-36.net/rohrpost
Log | Files | Refs | LICENSE

commit 138f1bf78d0f6f4cea849b9ef87268811c4b8b90
parent 5c204376213ec37399d68aca4abd0abfea2366bd
Author: Christoph Lohmann <20h@r-36.net>
Date:   Tue, 21 Aug 2012 16:22:45 +0200

Add charset guessing. This is lame but does it for sure.

Diffstat:
bin/rpopen | 2+-
bin/rpsyncmail | 2+-
meta.c | 2+-
mime.c | 65++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
mime.h | 1+
scan.c | 8++++----
util.c | 2+-
view.c | 4++--
8 files changed, 73 insertions(+), 13 deletions(-)

diff --git a/bin/rpopen b/bin/rpopen @@ -15,7 +15,7 @@ fi msgid="$*" -url=`rpview $msgid | awk '/URL:/ {print $2}' | tr -d '\r'` +url=`rpview $msgid | awk '/^URL:/ {print $2}' | tr -d '\r'` for i in $url do echo $i diff --git a/bin/rpsyncmail b/bin/rpsyncmail @@ -1,6 +1,6 @@ #!/bin/sh -if [ "$1" = "mb" ]; +if [ "$1" = "mb" ] || [ $# -eq 0 ]; then dsync -R -u chrissi mirror chrissi@r-36.net else diff --git a/meta.c b/meta.c @@ -73,7 +73,7 @@ meta_headers2meta(mime_t *mime) rhdr = llist_new(); forllist(meta->hdrs, header) { - enc = mime_decodeheader(header->data); + enc = mime_guessheader(header->data); if (enc == NULL) continue; diff --git a/mime.c b/mime.c @@ -295,6 +295,65 @@ mime_decodeheader(char *value) return ret; } +char *cstries[] = { + "utf-8", + "iso-8859-1", + "windows-1252", + "Shift_JIS", + "Big5", + "iso-8859-15", + NULL +}; + +char * +mime_guesscharset(char *str) +{ + int i, eq; + char *itry; + + for (i = 0; i < nelem(cstries); i++) { + itry = mime_iconv(str, cstries[i], cstries[i]); + if (itry == NULL) + continue; + eq = strcmp(str, itry); + free(itry); + if (!eq) + break; + } + + return cstries[i]; +} + +char * +mime_guessheader(char *value) +{ + char *nvalue, *gcs; + + gcs = NULL; + + nvalue = value; + if (!strisascii(value)) { + /* + * Guessing begins. Some major MUA developers did not read any + * RFCs. + */ + + gcs = mime_guesscharset(value); + if (gcs != NULL) { + nvalue = mime_iconv(value, gcs, "utf-8"); + if (nvalue == NULL) { + nvalue = value; + gcs = NULL; + } + } + } + + value = mime_decodeheader(nvalue); + if (gcs != NULL) + free(nvalue); + return value; +} + char * mime_decodeparam(char *value) { @@ -1173,7 +1232,7 @@ mime_filename(mime_t *mime) if (hdrp != NULL) { name = llist_ciget(hdrp, "filename"); if (name != NULL && name->data != NULL) { - filename = mime_decodeheader( + filename = mime_guessheader( (char *)name->data); } } @@ -1192,7 +1251,7 @@ mime_filename(mime_t *mime) if (hdrp != NULL) { name = llist_ciget(hdrp, "name"); if (name != NULL && name->data != NULL) { - filename = mime_decodeheader( + filename = mime_guessheader( (char *)name->data); } } @@ -1221,7 +1280,7 @@ mime_mkfilename(char *id, mime_t *mime) */ hdr = llist_ciget(mime->hdrs, "Content-Description"); if (hdr != NULL && hdr->data != NULL) { - filename = mime_decodeheader((char *)hdr->data); + filename = mime_guessheader((char *)hdr->data); if (filename != NULL) return filename; } diff --git a/mime.h b/mime.h @@ -36,6 +36,7 @@ char *mime_iconv(char *str, char *from, char *to); char *mime_decodeheaderext(char *value); int mime_isextws(char *str, int len); char *mime_decodeheader(char *value); +char *mime_guessheader(char *value); char *mime_decodeparam(char *value); char *mime_encodestring(char *value); char *mime_encodeheader(char *header, char *value); diff --git a/scan.c b/scan.c @@ -93,7 +93,7 @@ scanmain(int argc, char *argv[]) frome = llist_ciget(mime->hdrs, "from"); if (subjecte != NULL) { - subject = mime_decodeheader((char *)subjecte->data); + subject = mime_guessheader((char *)subjecte->data); } else { subject = "<empty>"; } @@ -110,7 +110,7 @@ scanmain(int argc, char *argv[]) } if (frome != NULL) { - from = mime_decodeheader((char *)frome->data); + from = mime_guessheader((char *)frome->data); } else { from = "<empty>"; } @@ -165,7 +165,7 @@ scanmain(int argc, char *argv[]) id = (char *)ide->data; if (subjecte != NULL) { - subject = mime_decodeheader((char *)subjecte->data); + subject = mime_guessheader((char *)subjecte->data); } else { subject = "<empty>"; } @@ -182,7 +182,7 @@ scanmain(int argc, char *argv[]) } if (frome != NULL) { - from = mime_decodeheader((char *)frome->data); + from = mime_guessheader((char *)frome->data); } else { from = "<empty>"; } diff --git a/util.c b/util.c @@ -71,7 +71,7 @@ utilmain(int argc, char *argv[]) ress = mime_encodestring(works); printf("%s", ress); } else if (status & DECODE) { - ress = mime_decodeheader(works); + ress = mime_guessheader(works); printf("%s", ress); } else { free(works); diff --git a/view.c b/view.c @@ -141,7 +141,7 @@ view_printpart(char *id, mime_t *mime, llist_t *dhdrs, llist_t *partl, didprint = 0; if (!strcasecmp(dhdrs->first->key, "all")) { forllist(mime->hdrs, helem) { - hvalue = mime_decodeheader((char *)helem->data); + hvalue = mime_guessheader((char *)helem->data); if (hvalue == NULL) continue; if (options & PRINT_VALUE) { @@ -157,7 +157,7 @@ view_printpart(char *id, mime_t *mime, llist_t *dhdrs, llist_t *partl, hlist = llist_cifind(mime->hdrs, delem->key); if (hlist != NULL) { forllist(hlist, helem) { - hvalue = mime_decodeheader( + hvalue = mime_guessheader( (char *)helem->data); if (hvalue == NULL) continue;