diff -rcN exim-4.14-orig/OS/Makefile-Base exim-4.14/OS/Makefile-Base
*** exim-4.14-orig/OS/Makefile-Base	Tue Mar 11 21:20:16 2003
--- exim-4.14/OS/Makefile-Base	Wed May  7 01:27:14 2003
***************
*** 250,256 ****
          directory.o dns.o drtables.o enq.o exim.o expand.o filter.o globals.o \
          header.o host.o ip.o log.o lss.o match.o moan.o \
          os.o parse.o queue.o \
!         rda.o readconf.o receive.o retry.o rewrite.o \
          route.o search.o smtp_in.o smtp_out.o spool_in.o spool_out.o \
          store.o string.o tls.o tod.o transport.o tree.o verify.o \
          local_scan.o $(EXIM_PERL)
--- 250,256 ----
          directory.o dns.o drtables.o enq.o exim.o expand.o filter.o globals.o \
          header.o host.o ip.o log.o lss.o match.o moan.o \
          os.o parse.o queue.o \
!         rda.o readconf.o receive.o retry.o rewrite.o rfc2047.o \
          route.o search.o smtp_in.o smtp_out.o spool_in.o spool_out.o \
          store.o string.o tls.o tod.o transport.o tree.o verify.o \
          local_scan.o $(EXIM_PERL)
***************
*** 486,491 ****
--- 486,492 ----
  receive.o:       $(HDRS) receive.c
  retry.o:         $(HDRS) retry.c
  rewrite.o:       $(HDRS) rewrite.c
+ rfc2047.o:       $(HDRS) rfc2047.c
  route.o:         $(HDRS) route.c
  search.o:        $(HDRS) search.c
  smtp_in.o:       $(HDRS) smtp_in.c
diff -rcN exim-4.14-orig/scripts/MakeLinks exim-4.14/scripts/MakeLinks
*** exim-4.14-orig/scripts/MakeLinks	Tue Mar 11 21:20:18 2003
--- exim-4.14/scripts/MakeLinks	Wed May  7 01:27:14 2003
***************
*** 205,210 ****
--- 205,211 ----
  ln -s ../src/receive.c         receive.c
  ln -s ../src/retry.c           retry.c
  ln -s ../src/rewrite.c         rewrite.c
+ ln -s ../src/rfc2047.c         rfc2047.c
  ln -s ../src/route.c           route.c
  ln -s ../src/search.c          search.c
  ln -s ../src/smtp_in.c         smtp_in.c
diff -rcN exim-4.14-orig/src/EDITME exim-4.14/src/EDITME
*** exim-4.14-orig/src/EDITME	Tue Mar 11 21:20:18 2003
--- exim-4.14/src/EDITME	Wed May  7 02:02:45 2003
***************
*** 787,790 ****
--- 787,800 ----
  
  # SUPPORT_MOVE_FROZEN_MESSAGES=yes
  
+ 
+ #------------------------------------------------------------------------------
+ # If you want to decode MIME-encoded headers with iconv library, uncomment
+ # the following lines.  ICONV_FILTER_ENCODING is the encoding language of
+ # filters, and you may use anything like 'UTF-8' or 'EUCjp' as long as your
+ # iconv understands it.
+ 
+ # HAVE_ICONV=yes
+ # FILTER_ENCODING=\"UTF-8\"
+ 
  # End of EDITME for Exim 4.
diff -rcN exim-4.14-orig/src/config.h.defaults exim-4.14/src/config.h.defaults
*** exim-4.14-orig/src/config.h.defaults	Tue Mar 11 21:20:19 2003
--- exim-4.14/src/config.h.defaults	Wed May  7 02:03:37 2003
***************
*** 38,45 ****
--- 38,49 ----
  /* Both uid and gid are triggered by this */
  #define EXIM_UID
  
+ #define FILTER_ENCODING            "UTF-8"
+ 
  #define HAVE_CRYPT16
  #define HAVE_SA_LEN
+ #define HAVE_ICONV
+ 
  #define HEADER_MAXSIZE            (1024*1024)
  
  #define INPUT_DIRECTORY_MODE       0750
diff -rcN exim-4.14-orig/src/expand.c exim-4.14/src/expand.c
*** exim-4.14-orig/src/expand.c	Tue Mar 11 21:20:20 2003
--- exim-4.14/src/expand.c	Wed May  7 01:27:14 2003
***************
*** 974,979 ****
--- 974,980 ----
  if (comma != 0 && ptr > yield) ptr -= 2;
  if (!want_raw) while (ptr > yield && isspace(ptr[-1])) ptr--;
  *ptr = 0;
+ if (!want_raw) return rfc2047_decode(yield);
  return yield;
  }
  
diff -rcN exim-4.14-orig/src/functions.h exim-4.14/src/functions.h
*** exim-4.14-orig/src/functions.h	Tue Mar 11 21:20:20 2003
--- exim-4.14/src/functions.h	Wed May  7 01:27:14 2003
***************
*** 275,280 ****
--- 275,281 ----
  extern int     tree_insertnode(tree_node **, tree_node *);
  extern tree_node *tree_search(tree_node *, uschar *);
  extern void    tree_write(tree_node *, FILE *);
+ extern uschar *rfc2047_decode(uschar *);
  
  extern int     verify_address(address_item *, FILE *, int, int, BOOL *);
  extern int     verify_check_dnsbl(uschar **);
diff -rcN exim-4.14-orig/src/rfc2047.c exim-4.14/src/rfc2047.c
*** exim-4.14-orig/src/rfc2047.c	Thu Jan  1 09:00:00 1970
--- exim-4.14/src/rfc2047.c	Wed May  7 02:04:09 2003
***************
*** 0 ****
--- 1,349 ----
+ /*
+  * rfc2047.c:
+  *   MIME decoding library, esp for exim Internet Mailer.
+  *
+  *   by Norihisa Washitake <nori@washitake.com>
+  *     You may find the latest version of this library
+  *     at http://washitake.com/mail/exim/mime/
+  *
+  * What is this? ----
+  *   Email messages written in multi-byte languages, including
+  *   Japanese language (in which I speak), usually have MIME encoded
+  *   headers as defined in RFC 2047.  It makes filtering of messages a
+  *   little bit difficult, so here is a library to enable decoding the
+  *   headers.
+  *
+  * References ----
+  *   RFC-2047 at http://www.ietf.org/rfc/rfc2047.txt
+  *
+  * Usage ----
+  *   extern char* rfc2047_decode(char *);
+  *      :
+  *   char *str = "encoded string...brah blah...";
+  *   char *ptr = rfc2047_decode(str);
+  *     [ some other things... ]
+  *   free(ptr);
+  *   ptr = 0;
+  *   (That's all, easy huh?)
+  *
+  * Bugs ----
+  *   Though use of iconv library is recommended for accurate character
+  *   set conversions, I included an experimental conversion code as it
+  *   is not supported on some systems.
+  *   
+  */
+ 
+ #define HAVE_EXIM_H       /* Uncomment if this is a part of exim. */
+ /* #define HAVE_ICONV */  /* Uncomment if you want use iconv. */
+ 
+ 
+ #ifdef HAVE_EXIM_H
+   #include "exim.h"
+   #define rfc2047_malloc(x) store_get(x)
+   #define rfc2047_free(x)
+ #else
+   #include <stdio.h>
+   #include <stdlib.h>
+ 
+   #define uschar            unsigned char
+   #define rfc2047_malloc(x) malloc(x)
+   #define rfc2047_free(x)   free(x); x=0
+ 
+   #define Ustrlen           strlen
+   #define Ustrcmp           strcmp
+   #define US                (unsigned char*)
+ #endif
+ 
+ 
+ #ifdef HAVE_ICONV
+   #include <iconv.h>
+   #ifndef FILTER_ENCODING
+     #define FILTER_ENCODING "UTF-8"
+   #endif
+ #endif
+ 
+ uschar* rfc2047_decode(uschar *);
+ 
+ int     rfc2047_strcat(uschar *, uschar *, int, int);
+ int     rfc2047_strstr(uschar *, int, int, uschar *);
+ uschar* rfc2047_decode_main(uschar *, uschar *, uschar *);
+ int     rfc2047_quotedprintable(uschar *, uschar **);
+ 
+ /* from auths/b64decode.c in exim source... */
+ extern int auth_b64decode(uschar *code, uschar **ptr);
+ 
+ uschar* rfc2047_conv_chset(uschar *, uschar *);
+ #if !defined(HAVE_ICONV)
+   /* character set conversion routines...
+    *
+    *   Although use of iconv library is recommended, some older versions
+    *   of iconv are either buggy or does not support UTF-8 or iconv is
+    *   not by some OS.  So we have our own converting functions for these
+    *   environments.
+    */
+ uschar* rfc2047_jis2euc(uschar *);
+ #endif   /* #if !defined(HAVE_ICONV) */
+ 
+ int rfc2047_strcat(uschar* to, uschar* from, int idx, int len)
+ {
+   register int i, j;
+   i = 0, j = idx;
+ 
+   while (j < len)
+     to[i++] = from[j++];
+   to[i] = '\0';
+ 
+   return (int)i;
+ }
+ 
+ int rfc2047_strstr(uschar* src, int beg, int end, uschar* portion)
+ {
+   int pos, p_len, end2, i;
+   int flg;
+ 
+   if (beg < 0)
+     return -1;
+ 
+   p_len = strlen(portion);
+   end2 = end - p_len + 1;
+ 
+   for (pos=beg; pos<end2; pos++) {
+     flg = 0;
+     for (i=0; i<p_len; i++)
+       if (src[pos+i] != portion[i])
+         flg = 1;
+     if (flg == 0)
+       return pos;
+   }
+ 
+   return -1;
+ }
+ 
+ uschar* rfc2047_decode_main(uschar* chset, uschar* enc, uschar* buf)
+ {
+   uschar* ptr = NULL;
+   uschar* result = NULL;
+   size_t len;
+ 
+   /* result of conversion should be stored in buf itself,
+      in case of no conversion.
+    */
+ 
+   if (enc[0] == 'B' || enc[0] == 'b') {
+     auth_b64decode(buf, &ptr);
+     strcpy(buf, ptr);
+   } else if (enc[0] == 'Q' || enc[0] == 'q') {
+     rfc2047_quotedprintable(buf, &ptr);
+     strcpy(buf, ptr);
+   } else {
+     len = strlen(buf);
+     ptr = rfc2047_malloc(len + 1);
+     memcpy(ptr, buf, len+1);
+   }
+ 
+   result = rfc2047_conv_chset(chset, ptr);
+   if (ptr != 0) rfc2047_free(ptr);
+   return result;
+ }
+ 
+ #define rfc2047_hex2n(h) \
+  (('0' <= h && h <= '9') ? (h - '0') : \
+   (('A' <= h && h <= 'F') ? (h - 'A' + 10) : \
+    (('a' <= h && h <= 'f') ? (h - 'a' + 10) : 0xff)))\
+ 
+ int rfc2047_quotedprintable(uschar* src, uschar** ptr)
+ {
+   register int i,j;
+   int srclen;
+   uschar* buf;
+   uschar c, c1, c2;
+ 
+   srclen = strlen(src);
+   buf = rfc2047_malloc(srclen + 1);
+   *ptr = buf;
+ 
+   i = j = 0;
+   while (i < srclen) {
+     c = src[i];
+     if (c == '=') {
+       if ((c1 = rfc2047_hex2n(src[i+1])) != 0xff)
+ 	if ((c2 = rfc2047_hex2n(src[i+2])) != 0xff) {
+ 	  c = (uschar)(c1*16 + c2);
+           i += 2;
+         }
+     }
+     i++;
+     buf[j++] = c;
+   }
+   buf[j] = '\0';
+ 
+   return j;
+ }
+ 
+ #undef rfc2047_hex2n
+ 
+ uschar* rfc2047_conv_chset(uschar* chset, uschar *src)
+ {
+ 
+ #ifdef HAVE_ICONV
+ 
+   iconv_t icd;
+   size_t len, inleft, outlen, outleft;
+   uschar* p = NULL;
+   uschar* buf = NULL;
+   uschar* buf2 = NULL;
+   uschar* s = src;
+   int i;
+ 
+   inleft = len = Ustrlen(src);
+   outlen = outleft = (size_t)256;
+   p = buf = rfc2047_malloc(outleft + 1);
+ 
+   icd = iconv_open(FILTER_ENCODING, chset);
+ 
+   if (icd == (iconv_t)-1) {
+     memcpy(buf, src, len+1);
+     return buf;
+   }
+   if (iconv(icd, (char**)&s, &inleft, (char**)&p, &outleft) == (size_t)-1) {
+     iconv_close(icd);
+     memcpy(buf, src, len+1);
+     return buf;
+   }
+   *p = '\0';
+   iconv_close(icd);
+ 
+   buf2 = rfc2047_malloc(outlen - outleft + 1);
+   memcpy(buf2, buf, outlen - outleft + 1);
+   rfc2047_free(buf);
+   return buf2;
+ 
+ #else
+ 
+   uschar* buf;
+   size_t len;
+ 
+   if (Ustrcmp(chset, US"ISO-2022-JP") == 0) {
+     buf = rfc2047_jis2euc(src);
+   } else {
+     len = Ustrlen(src);
+     buf = rfc2047_malloc(len + 1);
+     memcpy(buf, src, len + 1);
+   }
+   return buf;
+ #endif   /* #if defined(HAVE_ICONV) */
+ }
+ 
+ #if !defined(HAVE_ICONV)
+ uschar* rfc2047_jis2euc(uschar* src)
+ {
+   int i = 0, j = 0;
+   int isknj = 0;
+   uschar* res;
+   
+   /* In iso-2022-jp to euc-jp conversion, As the result is always
+    * shorter than the source so there is no need to calculate the
+    * length of the result.  Users of other encodes should calculate it
+    * first.  Hmm, so it is not a good example. */
+ 
+   res = rfc2047_malloc(Ustrlen(src) + 1);
+   while (src[i]) {
+     if (src[i] == 0x1B) {
+       switch (src[i+1]) {
+       case '$':
+ 	if (src[i+2] == '@' || src[i+2] == 'B') isknj = 3;
+ 	break;
+       case '(':
+ 	if (src[i+2] == 'B' || src[i+2] == 'J') isknj = 2;
+ 	break;
+       }
+       if (isknj & 2) {
+ 	i += 3;
+ 	isknj = (isknj & 1);
+       } else
+ 	res[j++] = src[i++];
+     } else {
+       if (isknj) {
+ 	res[j++] = src[i++] | 0x80;
+ 	res[j++] = src[i++] | 0x80;
+       } else
+ 	res[j++] = src[i++];
+     }
+   }
+   res[j] = '\0';
+   return res;
+ }
+ 
+ /* Add other conversions if required. */
+ 
+ #endif  /* #if !defined(HAVE_ICONV)... */
+ 
+ uschar* rfc2047_decode(uschar* src)
+ {
+   int idx, idx2, len, test;
+   register int i, j;
+   uschar* res;
+   uschar* buf;
+   uschar* result;
+   uschar* decoded;
+   uschar prevch = '\0';
+   
+   len = strlen(src);
+   buf = rfc2047_malloc(len + 1);  /* working buffer */
+   res = rfc2047_malloc(len + 1);  /* result */
+   
+   i = j = 0;
+   while (i < len) {
+     if (src[i] == '\x0D' || src[i] == '\x0A') {
+       i += (src[i] == '\x0D' && src[i+1] == '\x0A') ? 2 : 1;
+       while (src[i] == ' '  || src[i] == '\t') i++;
+       if (src[i] != '=' || prevch != '=')
+         buf[j++] = ' ';
+     }
+     prevch = src[i++];
+     buf[j++] = prevch;
+   }
+   buf[j] = '\0';
+   len = j;
+   
+   idx = idx2 = 0;
+   
+   while ((test = rfc2047_strstr(buf, idx, len, "=?")) >= 0) {
+     int i1, i2, i3;
+     idx2 += rfc2047_strcat(&res[idx2], buf, idx, test);
+     
+     i1 = rfc2047_strstr(buf, test+2,  len, "?");
+     i2 = rfc2047_strstr(buf, i1+1,    len, "?");
+     i3 = rfc2047_strstr(buf, i2+1,    len, "?=");
+     if (i3 < 0) {
+       /* it is not a mime-encoding flagment, and no more mime. */
+       idx2 += rfc2047_strcat(&res[idx2], buf, test, len);
+       idx = len;
+     } else {
+       /* think : =?iso2022jp?B?Gyx/.....?= */
+       /*         test       i1i2        i3 */
+       uschar* charset = &buf[test+2];
+       uschar* enc     = &buf[i1+1];
+       uschar* encstr  = &buf[i2+1];
+       buf[i1] = '\0'; buf[i2] = '\0'; buf[i3] = '\0';
+       
+       decoded = rfc2047_decode_main(charset, enc, encstr);
+       idx2 += rfc2047_strcat(&res[idx2], decoded, 0, strlen(decoded));
+       idx = i3 + 2;
+       rfc2047_free(decoded);
+       
+       if (test>1 && idx<len)
+ 	if (buf[test-1] == ' ' && buf[idx] == ' ')
+ 	  idx++;
+     }
+   }
+   if (idx < len)
+     idx2 += rfc2047_strcat(&res[idx2], buf, idx, len);
+   
+   result = rfc2047_malloc(idx2 + 1);
+   strcpy(result, res);
+   rfc2047_free(res);
+   rfc2047_free(buf);
+   
+   return result;
+ }
