The following patches enable RFC1342 compatible decoding of header fields for non-ascii character sets. Additional tips: setenv MM_CHARSET setenv LC_TYPE e.g. setenv MM_CHARSET KOI8-R setenv LC_TYPE ru_RU.KOI8-R or setenv MM_CHARSET iso-8859-1 setenv LC_TYPE iso_8859_1 Change your mhl.format to read so that the new code will be invoked on interesting fields when you do a "show": From:formatfield="%(comp{text})" Reply-To:formatfield="%(comp{text})" To:formatfield="%(comp{text})" cc:formatfield="%(comp{text})" --------------------------------------------------------- --- conf/FreeBSD.orig Sat Oct 12 23:04:23 1996 +++ conf/FreeBSD Sat Oct 12 23:36:19 1996 @@ -18,7 +20,7 @@ options BSD42 BSD43 BSD44 WAITINT UNISTD VSPRINTF MORE='"/usr/bin/more"' options NORUSERPASS DBMPWD POSIX NTOHLSWAP SYS5DIR OVERHEAD MSGID FCNTL options BIND MIME SENDMTS SMTP WHATNOW ZONEINFO -options GCOS_HACK RENAME LOCALE +options GCOS_HACK RENAME LOCALE RFC1342 # If you want POP support, this will help you get started, but feel # free to customize it. --- conf/makefiles/sbr.864 Sun Oct 13 01:15:28 1996 +++ conf/makefiles/sbr Sun Oct 13 01:15:50 1996 @@ -50,7 +50,7 @@ ruserpass.c \ @END: NORUSERPASS showfile.c smatch.c sprintb.c ssequal.c strindex.c trimcpy.c \ - uleq.c uprf.c vfgets.c formatdef.c m_msgdef.c + uleq.c uprf.c vfgets.c formatdef.c m_msgdef.c rfc1342.c OFILES = add.o adios.o admonish.o addrsbr.o advertise.o advise.o \ @@ -69,7 +69,7 @@ ruserpass.o \ @END: NORUSERPASS showfile.o smatch.o sprintb.o ssequal.o strindex.o trimcpy.o \ - uleq.o uprf.o vfgets.o formatdef.o m_msgdef.o + uleq.o uprf.o vfgets.o formatdef.o m_msgdef.o rfc1342.o @BEGIN: SHAREDLIB ODEFS = formatdef.o m_msgdef.o --- sbr/formatsbr.c.orig Sat Oct 12 23:05:07 1996 +++ sbr/formatsbr.c Sun Oct 13 00:08:31 1996 @@ -114,13 +114,13 @@ */ static int match (str, sub) -register char *str, - *sub; +register unsigned char *str, + *sub; { register int c1; register int c2; - register char *s1; - register char *s2; + register unsigned char *s1; + register unsigned char *s2; #ifdef LOCALE while (c1 = *sub) { @@ -203,14 +203,14 @@ i++;\ }\ } else {\ - while ((c = *sp) && (iscntrl(c) || isspace(c)))\ + while ((c = (unsigned char) *sp) && (iscntrl(c) || isspace(c)))\ sp++;\ }\ - while ((c = *sp++) && --i >= 0 && cp < ep)\ + while ((c = (unsigned char) *sp++) && --i >= 0 && cp < ep)\ if (isgraph(c)) \ *cp++ = c;\ else {\ - while ((c = *sp) && (iscntrl(c) || isspace(c)))\ + while ((c = (unsigned char) *sp) && (iscntrl(c) || isspace(c)))\ sp++;\ *cp++ = ' ';\ }\ @@ -221,13 +221,13 @@ } #define PUTS(cp, str) {\ if (sp = (str)) {\ - while ((c = *sp) && (iscntrl(c) || isspace(c)))\ + while ((c = (unsigned char) *sp) && (iscntrl(c) || isspace(c)))\ sp++;\ - while((c = *sp++) && cp < ep)\ + while((c = (unsigned char) *sp++) && cp < ep)\ if (isgraph(c)) \ *cp++ = c;\ else {\ - while ((c = *sp) && (iscntrl(c) || isspace(c)))\ + while ((c = (unsigned char) *sp) && (iscntrl(c) || isspace(c)))\ sp++;\ *cp++ = ' ';\ }\ @@ -358,15 +358,30 @@ long l; char *savestr; char buffer[BUFSIZ]; + char workbuff[BUFSIZ]; while (cp < ep) { switch (fmt->f_type) { case FT_COMP: +#ifdef RFC1342 + str = fmt->f_comp->c_text; + if (maybe_decode_rfc1342(str, buffer)) + str = buffer; + PUTS (cp, str); +#else PUTS (cp, fmt->f_comp->c_text); +#endif break; case FT_COMPF: +#ifdef RFC1342 + str = fmt->f_comp->c_text; + if (maybe_decode_rfc1342(str, buffer)) + str = buffer; + PUTSF (cp, str, fmt->f_width, fmt->f_fill); +#else PUTSF (cp, fmt->f_comp->c_text, fmt->f_width, fmt->f_fill); +#endif break; case FT_LIT: @@ -500,6 +515,10 @@ case FT_LS_COMP: str = fmt->f_comp->c_text; +#ifdef RFC1342 + if (maybe_decode_rfc1342(str, buffer)) + str = buffer; +#endif break; case FT_LS_LIT: str = fmt->f_text; @@ -722,6 +741,10 @@ else break; } +#ifdef RFC1342 + if (maybe_decode_rfc1342(str, workbuff)) + str = workbuff; +#endif /* RFC1342 */ if (*str) break; } @@ -744,6 +767,10 @@ break; } } +#ifdef RFC1342 + if (maybe_decode_rfc1342(str, workbuff)) + str = workbuff; +#endif /* RFC1342 */ #endif /* BERK */ break; --- /dev/null Sat Oct 12 23:27:32 1996 +++ sbr/rfc1342.c Sun Oct 13 00:02:22 1996 @@ -0,0 +1,184 @@ +/* rfc1342.c */ +/* + * Decode RFC1342 header format + */ + +#ifdef RFC1342 +static char hexindex[] = { + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1, + -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 +}; + +static char index_64[128] = { + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, + 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, + 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, + -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, + 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 +}; + +#define char64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) + +static int +unqp (byte1, byte2) + char byte1; + char byte2; +{ + if (hexindex[byte1] == -1 || hexindex[byte2] == -1) + return -1; + return hexindex[byte1]<<4 | hexindex[byte2]; +} + +int +maybe_decode_rfc1342 (src, dst) + char *src; + char *dst; +{ + static char *mm_charset = 0; + static char *alt_charset = 0; + extern char *getenv(); + char *p; + char *q; + char *pp; + char *startofmime = 0; + char *endofmime = 0; + int c; + int quoted_printable; + + if (!mm_charset) { + mm_charset = getenv ("MM_CHARSET"); + if (mm_charset && strcasecmp(mm_charset, "iso-8859-1") == 0) { + alt_charset = "us-ascii"; /* Accept a common subset */ + } + } + if (!mm_charset || src == 0) + return 0; + + for (p = src, q = dst; *p; p++) { + *q++ = *p; + if (*p == '=' && p[1] && p[1] == '?' && p[2]) { + /* Have: =? */ + startofmime = p + 2; + if (strncasecmp(startofmime, mm_charset, + strlen(mm_charset)) == 0) { + startofmime += strlen (mm_charset); + } else if (alt_charset && + (strncasecmp(startofmime, alt_charset, + strlen(alt_charset)) == 0)) { + startofmime += strlen (alt_charset); + } else { + continue; + } + /* Have: =?charset */ + if (startofmime[0] != '?') + continue; + /* Have: =?charset? */ + startofmime++; + if (*startofmime != 'B' && + *startofmime != 'b' && + *startofmime != 'Q' && + *startofmime != 'q') + continue; + /* Have: =?charset?E */ + quoted_printable = *startofmime == 'Q' || + *startofmime == 'q';; + startofmime++; + if (*startofmime != '?') + continue; + /* Have: =?charset?E? */ + startofmime++; + for (pp = startofmime; *pp && *(pp+1); pp++) + if (*pp == '?' && pp[1] == '=') { + endofmime = pp; + break; + } + /* Have: =?charset?E?text?= */ + if (endofmime) { + q--; + if (quoted_printable) + for (pp = startofmime; pp < endofmime; pp++) { + if (*pp == '=') { + c = unqp (pp[1], pp[2]); + if ( c == -1) + continue; + if ( c != 0) + *q++ = c; + pp += 2; + } else if (*pp == '_') + *q++ = ' '; + else + *q++ = *pp; + } + else { /* base64 */ + int c1, c2, c3, c4; + pp = startofmime; + while (pp < endofmime) { + /* 6 + 2 bits */ + while ((pp < endofmime) && + ((c1 = char64(*pp)) == -1)) { + pp++; + } + if (pp < endofmime) { + pp++; + } + while ((pp < endofmime) && + ((c2 = char64(*pp)) == -1)) { + pp++; + } + if (pp < endofmime && c1 != -1 && c2 != -1) { + *q++ = (c1 << 2) | (c2 >> 4); + pp++; + } + /* 4 + 4 bits */ + while ((pp < endofmime) && + ((c3 = char64(*pp)) == -1)) { + pp++; + } + if (pp < endofmime && c2 != -1 && c3 != -1) { + *q++ = ((c2 & 0xF) << 4) | (c3 >> 2); + pp++; + } + /* 2 + 6 bits */ + while ((pp < endofmime) && + ((c4 = char64(*pp)) == -1)) { + pp++; + } + if (pp < endofmime && c3 != -1 && c4 != -1) { + *q++ = ((c3 & 0x3) << 6) | (c4); + pp++; + } + } + } + p = endofmime + 1; + if (*p == ' ') + p++; + } + } + } + *q = 0; + return endofmime != 0; +} +#endif + +#ifdef notdef /* For debugging */ +int +main(argc, argv) + int argc; + char **argv; +{ + char buff[100]; + if (maybe_decode_rfc1342 (argv[1], buff)) + puts (buff); + else + puts ("NEI!"); +} +#endif