Hi!

Ok, I attached the wrong patch.  This one should be better.

-- 
Kind regards,
+--------------------------------------------------------------------+
| Bas Zoetekouw              | GPG key: 0644fab7                     |
|----------------------------| Fingerprint: c1f5 f24c d514 3fec 8bf6 |
| [EMAIL PROTECTED], [EMAIL PROTECTED] |              a2b1 2bae e41f 0644 fab7 |
+--------------------------------------------------------------------+ 
diff -Naur slrn-0.9.8.1pl1.eerst/debian/changelog 
slrn-0.9.8.1pl1/debian/changelog
--- slrn-0.9.8.1pl1.eerst/debian/changelog      2006-03-31 18:03:56.000000000 
+0200
+++ slrn-0.9.8.1pl1/debian/changelog    2006-03-31 19:14:46.000000000 +0200
@@ -1,3 +1,9 @@
+slrn (0.9.8.1pl1-17) experimental; urgency=low
+
+  * Fixes to the charset patch 
+
+ -- Bas Zoetekouw <[EMAIL PROTECTED]>  Fri, 31 Mar 2006 18:05:14 +0200
+
 slrn (0.9.8.1pl1-16) experimental; urgency=low
 
   * Added charset patch from Bas Zoetekouw. (closes: #316919)
diff -Naur slrn-0.9.8.1pl1.eerst/debian/patches/00list 
slrn-0.9.8.1pl1/debian/patches/00list
--- slrn-0.9.8.1pl1.eerst/debian/patches/00list 2006-03-31 18:03:56.000000000 
+0200
+++ slrn-0.9.8.1pl1/debian/patches/00list       2006-03-31 19:14:38.000000000 
+0200
@@ -11,4 +11,3 @@
 208_slrnrc-conv.diff
 209_optic.diff
 210_doc-fix.diff
-300_iconv.diff
diff -Naur slrn-0.9.8.1pl1.eerst/configure.in slrn-0.9.8.1pl1/configure.in
--- slrn-0.9.8.1pl1.eerst/configure.in  2006-03-31 18:03:55.000000000 +0200
+++ slrn-0.9.8.1pl1/configure.in        2006-04-03 23:08:05.000000000 +0200
@@ -171,6 +171,7 @@
 
 fi
 
+
 dnl enforce the use of inews
 AH_VERBATIM([SLRN_FORCE_INEWS],
 [/* define if you want to force the use of inews */
@@ -353,6 +354,35 @@
 AC_DEFINE(SLRN_HAS_SPOOL_SUPPORT, 1)
 fi
 
+
+dnl iconv
+AM_ICONV
+AH_VERBATIM([SLRN_USE_ICONV],
+[/* define this if you want to use iconv */
+#undef SLRN_USE_ICONV])
+AC_ARG_ENABLE([iconv],
+       [  --enable-iconv          Enable use of iconv library],
+       AC_DEFINE([SLRN_USE_ICONV])
+       use_iconv=yes,
+       use_iconv=no)
+
+AH_VERBATIM([USE_ICONV],
+[/* This is defined if use of iconv is requested _and_ libiconv is available */
+#undef USE_ICONV])
+
+if test "x${use_iconv}" = "xyes"; 
+then
+       if test "x${am_cv_func_iconv}" != "xyes"
+       then
+               AC_MSG_FAILURE([Use of libiconv was requested, but the iconv 
library was not found.  Maybe you need to specify --with-libiconv-prefix?]);
+       fi
+       AC_MSG_NOTICE([We're using iconv])
+       AC_DEFINE([USE_ICONV])
+else
+       AC_MSG_NOTICE([We're NOT using iconv])
+fi
+
+
 AH_BOTTOM(
 [/* misc settings copied from the original config.hin file */
 
diff -Naur slrn-0.9.8.1pl1.eerst/src/art.c slrn-0.9.8.1pl1/src/art.c
--- slrn-0.9.8.1pl1.eerst/src/art.c     2006-03-31 18:03:55.000000000 +0200
+++ slrn-0.9.8.1pl1/src/art.c   2006-04-03 23:08:05.000000000 +0200
@@ -79,6 +79,13 @@
 # include "grplens.h"
 #endif
 
+/* don't use recode for slrnpull */
+#if defined(SLRNPULL_CODE) && defined(USE_ICONV)
+# undef USE_ICONV
+#endif
+
+
+
 /*}}}*/
 
 /*{{{ extern Global variables  */
@@ -616,6 +623,9 @@
      Slrn_Current_Article = NULL;
 
    free_article_lines (a);
+#ifdef USE_ICONV
+   slrn_free (a->charset);
+#endif
    slrn_free ((char *) a);
 }
 
@@ -2544,8 +2554,8 @@
 #if SLRN_HAS_MIME
             if ((do_mime == 0) && (Slrn_Use_Mime & MIME_DISPLAY))
               {
-                 slrn_rfc1522_decode_string (tmp);
-                 slrn_rfc1522_decode_string (h->from);
+                 slrn_rfc1522_decode_string (&tmp);
+                 slrn_rfc1522_decode_string (&(h->from));
               }
 #endif
             slrn_free (h->realname);
@@ -5509,22 +5519,44 @@
 static Slrn_Header_Type *process_xover (Slrn_XOver_Type *xov)
 {
    Slrn_Header_Type *h;
+   unsigned char *c;
    
    h = (Slrn_Header_Type *) slrn_safe_malloc (sizeof (Slrn_Header_Type));
    
    slrn_map_xover_to_header (xov, h);
    Number_Total++;
    
+#ifdef USE_ICONV
+   /* ok, some news client (Outlook Express *sigh*) just put unencoded
+    * latin1/9 chars in their headers.  As we don't know any charset at 
+    * this time, replace those chars by '?' chars */
+   c = h->subject;
+   while (*c!='\0' && *c!=0x0a && *c!=0x0d) 
+   { 
+          if (*c>=0x7f) *c = '?'; c++; 
+   }
+   c = h->from;
+   while (*c!='\0' && *c!=0x0a && *c!=0x0d) 
+   { 
+          if (*c>=0x7f) *c = '?'; c++; 
+   }
+#endif /* USE_ICONV */
+
 #if SLRN_HAS_MIME
    if (Slrn_Use_Mime & MIME_DISPLAY)
      {
-       slrn_rfc1522_decode_string (h->subject);
-       slrn_rfc1522_decode_string (h->from);
+       slrn_rfc1522_decode_string (&(h->subject));
+       slrn_rfc1522_decode_string (&(h->from));
      }
 #endif
 
    get_header_real_name (h);
+#ifdef USE_ICONV
+   /* TODO: do we translate here, or do we do it 
+       * in slrn_rfc1522_decode_string? */
+#else /* USE_ICONV */
    slrn_chmap_fix_header (h);
+#endif /* USE_ICONV */
    
 #if SLRN_HAS_GROUPLENS
    if (Slrn_Use_Group_Lens)
diff -Naur slrn-0.9.8.1pl1.eerst/src/art.h slrn-0.9.8.1pl1/src/art.h
--- slrn-0.9.8.1pl1.eerst/src/art.h     2006-03-31 18:03:56.000000000 +0200
+++ slrn-0.9.8.1pl1/src/art.h   2006-03-31 19:14:46.000000000 +0200
@@ -195,6 +195,9 @@
    int mime_needs_metamail;
 #endif
    int needs_sync;                    /* non-zero if line number/current line 
needs updated */
+#ifdef USE_ICONV
+   char * charset;             /* charset from content-type header */
+#endif
 }
 Slrn_Article_Type;
 
diff -Naur slrn-0.9.8.1pl1.eerst/src/chmap.c slrn-0.9.8.1pl1/src/chmap.c
--- slrn-0.9.8.1pl1.eerst/src/chmap.c   2006-03-31 18:03:56.000000000 +0200
+++ slrn-0.9.8.1pl1/src/chmap.c 2006-03-31 21:12:27.000000000 +0200
@@ -1,4 +1,6 @@
 /* -*- mode: C; mode: fold; -*- */
+/* vim:ts=8:sw=2:expandtab 
+ */
 /*
  This file is part of SLRN.
 
@@ -47,15 +49,149 @@
 #include "art.h"
 #include "chmap.h"
 
-#if SLRN_HAS_CHARACTER_MAP
-char *Slrn_Charset;
+#ifdef USE_ICONV
+#include <locale.h>
+#include <langinfo.h>
+#include <iconv.h>
+#include <errno.h>
+#endif
 
-static unsigned char *ChMap_To_Iso_Map;
-static unsigned char *ChMap_From_Iso_Map;
+/* don't use recode for slrnpull */
+#if defined(SLRNPULL_CODE) && defined(USE_ICONV)
+# undef USE_ICONV
+#endif
+
+
+#if SLRN_HAS_CHARACTER_MAP || defined(USE_ICONV)
+
+/* if we use recode, this is set from the environment locale, otherwise it is
+ * specified by the user in the config file */
+char *Slrn_Charset;
 
 /* This include file contains static globals */
 # include "charmaps.h"
 
+#endif /* SLRN_HAS_CHARACTER_MAP || defined(USE_ICONV) */
+
+#ifdef USE_ICONV
+
+const iconv_t ICONV_FAIL = (iconv_t) -1;
+
+/* translate the string *str_ptr from charset cs_from to charset cs_to */
+/* str_ptr will be freed and reallocated */
+char * slrn_chmap_translate_string (
+    char *cs_from, char *cs_to, char **str_ptr)
+  {
+    iconv_t cd;
+    char *retval;
+    char *cs_to_translit;
+    char *str = *str_ptr;
+    size_t in_len, in_left, out_len, out_left;
+    char *in_start, *in_cursor, *out_start, *out_cursor;
+    size_t num;
+
+
+    /* make sure the charsets are initialized */
+    if (cs_from == NULL) cs_from = ICONV_DEFAULT_CHARSET;
+    if (cs_to   == NULL) return *str_ptr;
+
+    /* don't translate if from and to charsets are equal */
+    if (strcasecmp (cs_from, cs_to) == 0)
+      return 0;
+
+    /* concat "//translit" to cs_to */
+    cs_to_translit = slrn_safe_malloc( strlen (cs_to) + 10 + 1);
+    sprintf(cs_to_translit, "%s%s", cs_to, "//translit");
+
+    /* Initialize new translation description */
+    /* TODO: cache this and check cs_from and cs_to every time */
+    cd = iconv_open(cs_to_translit, cs_from);
+    if (cd == ICONV_FAIL)
+      {
+        slrn_error (_("Unsupported translation: %s->%s"), cs_from, cs_to);
+        return NULL;
+      }
+
+    /* number of bytes left in input/output buffers */
+    in_left  = in_len  = strlen (str);
+    out_left = out_len = 2 * strlen(str);
+    in_cursor  = in_start  = str;
+    out_cursor = out_start = slrn_safe_malloc( out_left + 1 );
+    
+    /* iterate until the entire line is translated */
+    while (1)
+    {
+      /* stop if there is nothing left to translate */
+      if (in_left == 0)
+      {
+        break;
+      }
+      
+      /* do the conversion */
+      num = iconv(cd, &in_cursor, &in_left, &out_cursor, &out_left);
+
+      /* the entire line was translated, we're done */
+      if (num>=0) 
+      {
+        break;
+      }
+
+      /* otherwise, an error occured */
+      switch (errno) /* these are the only error that can occur */
+      {
+        case EILSEQ: /* invalid byte sequence at pos in_cursor */
+          /* skip the invalid byte and continue */
+          if (in_left>0) /* otherwise we're done anyway */
+          {
+            in_left--;
+            in_cursor++;
+          }
+          break;
+        case E2BIG: /* output buff is full */
+          /* realloc the output buffer (make it 2 times as large) */
+          slrn_realloc(out_cursor, 2*out_len, 1);
+          out_left = out_len;
+          out_len *= 2;
+          break;
+        case EINVAL: /* incomplete byte sequence at end of string*/
+          /* just skip the rest of the line */
+          in_left = 0;
+          break;
+        case EBADF: /* cd is invalid */
+          slrn_error(_("Internal error while translating string"));
+          in_left = 0;
+          break;
+        default: /* never reached */
+          slrn_error(_("A unknown error occurred.  This should not happen."));
+          in_left = 0;
+          break;
+      }
+    }
+
+    /* make sure string ends in a \0 */
+    *out_cursor = '\0';
+
+    /* now copy the output buffer to a newly allocated string */
+    retval = slrn_safe_strmalloc (out_start);
+
+    /* free the old input string, and set it to the new result */
+    slrn_free (str);
+    *str_ptr = retval;
+
+    /* free variables */
+    slrn_free (out_start);
+    slrn_free (cs_to_translit);
+    iconv_close (cd);
+    
+    return retval;
+  }
+
+#else /* USE_ICONV */
+# if SLRN_HAS_CHARACTER_MAP
+
+static unsigned char *ChMap_To_Iso_Map;
+static unsigned char *ChMap_From_Iso_Map;
+
 static void chmap_map_string (char *str, unsigned char *map)
 {
    unsigned char ch;
@@ -69,11 +205,11 @@
 
 static void chmap_map_string_from_iso (char *str)
 {
-# if SLANG_VERSION >= 20000
+#  if SLANG_VERSION >= 20000
    /* fixme */
    if (Slrn_UTF8_Mode)
      return;
-#endif
+#  endif
    chmap_map_string (str, ChMap_From_Iso_Map);
 }
 
@@ -87,13 +223,17 @@
    chmap_map_string (str, ChMap_To_Iso_Map);
 }
 
-#endif
+# endif /*  SLRN_HAS_CHARACTER_MAP */
+
+#endif /* USE_ICONV */
 
 /* Fix a single header; the rest of the header lines are dealt with
  * later in hide_art_headers() */
+#ifndef USE_ICONV /* recode handles the translation directly while 
+                      decoding  the rfc1522 */
 void slrn_chmap_fix_header (Slrn_Header_Type *h)
 {
-#if SLRN_HAS_CHARACTER_MAP
+#if SLRN_HAS_CHARACTER_MAP 
    if ((h->flags & HEADER_CHMAP_PROCESSED) == 0)
      {
        chmap_map_string_from_iso (h->subject);
@@ -101,32 +241,62 @@
        chmap_map_string_from_iso (h->realname);
        h->flags |= HEADER_CHMAP_PROCESSED;
      }
-#endif
+#endif /* SLRN_HAS_CHARACTER_MAP  */
 }
 
+#endif
+
 void slrn_chmap_fix_body (Slrn_Article_Type *a, int revert)
 {
-#if SLRN_HAS_CHARACTER_MAP
+#if SLRN_HAS_CHARACTER_MAP || USE_ICONV
    Slrn_Article_Line_Type *l;
+   char * charset;
    
    if (a == NULL)
      return;
+
+#ifdef USE_ICONV
+   /* check if we need to translate */
+   if (a->charset == NULL)
+     charset = ICONV_DEFAULT_CHARSET;
+   else 
+     charset = a->charset;
+       
+   if (strcasecmp (Slrn_Charset, charset) == 0)
+     return;
+#endif
+   
    l = a->lines;
 
    while (l != NULL)
      {
-       if (revert)
-         chmap_map_string_to_iso (l->buf);
-       else
-         chmap_map_string_from_iso (l->buf);
-        l = l->next;
+# ifdef USE_ICONV
+       /* don't process headers */
+       if (l->flags & HEADER_LINE)
+       {
+         l = l->next;
+         continue;
+       }
+
+       if (revert)
+         slrn_chmap_translate_string (Slrn_Charset, charset, &(l->buf));
+       else
+         slrn_chmap_translate_string (charset, Slrn_Charset, &(l->buf));
+# else /* USE_ICONV */
+       if (revert)
+         chmap_map_string_to_iso (l->buf);
+       else
+        chmap_map_string_from_iso (l->buf);
+# endif /* USE_ICONV */
+       
+       l = l->next;
      }
 #endif
 }
 
 int slrn_chmap_fix_file (char *file, int reverse)
 {
-#if SLRN_HAS_CHARACTER_MAP
+#if SLRN_HAS_CHARACTER_MAP 
    FILE *fp, *tmpfp;
    char buf [4096];
    char tmp_file [SLRN_MAX_PATH_LEN];
@@ -170,8 +340,11 @@
    ret = 0;
    while (NULL != fgets (buf, sizeof (buf), fp))
      {
+#ifdef USE_ICONV
+#else
        if (reverse) chmap_map_string_from_iso (buf);
        else chmap_map_string_to_iso (buf);
+#endif
        if (EOF == fputs (buf, tmpfp))
          {
             slrn_error (_("Write Error. Disk Full? --- message not posted."));
@@ -219,8 +392,39 @@
 }
 #endif
 
+
+
 int slrn_set_charset (char *name)
 {
+#if USE_ICONV
+  iconv_t cd;
+
+  /* use environenment for locale */
+  setlocale (LC_ALL, "");
+  
+  /* get charset of current locale */
+  Slrn_Charset = slrn_safe_strmalloc (nl_langinfo (CODESET));
+
+  /* TODO: check that we don't have any UCS2 and UCS4 charsets, as those
+   * can't be handled at all.  Slrn works with 0-terminated strings, which 
+   * is totally incompatible with these charsets.  Luckily those are extremely 
+   * uncommon anyway on usenet. */
+
+  /* initialize recode engine to check if Slrn_Charset is valid */
+  cd = iconv_open ("UTF-8", Slrn_Charset);
+  if (cd == ICONV_FAIL)
+    {
+      slrn_error (_("Unsupport character set: %s"), Slrn_Charset);
+      return -1;
+    }
+
+  /* free variables */
+  iconv_close (cd);
+
+  return 0;
+  
+#else /* USE_ICONV */
+
 #if SLRN_HAS_CHARACTER_MAP
    CharMap_Type *map;
    unsigned int i;
@@ -254,4 +458,5 @@
    (void) name;
    return -1;
 #endif
+#endif /* USE_ICONV */
 }
diff -Naur slrn-0.9.8.1pl1.eerst/src/chmap.h slrn-0.9.8.1pl1/src/chmap.h
--- slrn-0.9.8.1pl1.eerst/src/chmap.h   2006-03-31 18:03:56.000000000 +0200
+++ slrn-0.9.8.1pl1/src/chmap.h 2006-03-31 19:14:46.000000000 +0200
@@ -20,8 +20,20 @@
 */
 #ifndef _SLRN_CHMAP_H
 #define _SLRN_CHMAP_H
+
+/* don't use recode for slrnpull */
+#if defined(SLRNPULL_CODE) && defined(USE_ICONV)
+# undef USE_ICONV
+#endif
+
+#define ICONV_DEFAULT_CHARSET "iso-8859-15"
+
 extern int slrn_set_charset (char *);
 extern int slrn_chmap_fix_file (char *, int);
+#ifdef USE_ICONV
+extern char * slrn_chmap_translate_string (
+       char *, char *, char **);
+#endif
 extern void slrn_chmap_fix_body (Slrn_Article_Type *, int);
 extern void slrn_chmap_fix_header (Slrn_Header_Type *);
 
diff -Naur slrn-0.9.8.1pl1.eerst/src/config.h.in slrn-0.9.8.1pl1/src/config.h.in
--- slrn-0.9.8.1pl1.eerst/src/config.h.in       2006-03-31 18:03:55.000000000 
+0200
+++ slrn-0.9.8.1pl1/src/config.h.in     2006-03-31 21:32:31.000000000 +0200
@@ -167,6 +167,9 @@
 /* Define to 1 if you have the `vsnprintf' function. */
 #undef HAVE_VSNPRINTF
 
+/* Define as const if the declaration of iconv() needs const. */
+#undef ICONV_CONST
+
 /* Define the directory where your locales are */
 #undef LOCALEDIR
 
@@ -263,9 +266,15 @@
 /* sendmail command */
 #undef SLRN_SENDMAIL_COMMAND
 
+/* define this if you want to use iconv */
+#undef SLRN_USE_ICONV
+
 /* Define to 1 if you have the ANSI C header files. */
 #undef STDC_HEADERS
 
+/* This is defined if use of iconv is requested _and_ libiconv is available */
+#undef USE_ICONV
+
 /* define if you have va_copy() in stdarg.h */
 #undef VA_COPY
 
diff -Naur slrn-0.9.8.1pl1.eerst/src/mime.c slrn-0.9.8.1pl1/src/mime.c
--- slrn-0.9.8.1pl1.eerst/src/mime.c    2006-03-31 18:03:56.000000000 +0200
+++ slrn-0.9.8.1pl1/src/mime.c  2006-03-31 20:29:43.000000000 +0200
@@ -1,4 +1,6 @@
 /* -*- mode: C; mode: fold -*- */
+/* vim:ts=8:expandtab:
+ */
 /* MIME handling routines.
  *
  * Author: Michael Elkins <[EMAIL PROTECTED]>
@@ -46,8 +48,15 @@
 #include "util.h"
 #include "server.h"
 #include "snprintf.h"
+#include "chmap.h"
 #include "mime.h"
 
+/* don't use recode for slrnpull */
+#if defined(SLRNPULL_CODE) && defined(USE_ICONV)
+# undef USE_ICONV
+#endif
+
+
 #if ! SLRN_HAS_MIME
 int Slrn_Use_Mime = 0;
 #else /* rest of file in this ifdef */
@@ -60,6 +69,12 @@
 
 char *Slrn_Mime_Display_Charset;
 
+#ifdef USE_ICONV
+static char *Compatible_Charsets[] =
+{
+   "US-ASCII",                        /* This MUST be zeroth element */
+};
+#else /* USE_ICONV */
 /* These are all supersets of US-ASCII.  Only the first N characters are 
  * matched, where N is the length of the table entry.
  */
@@ -73,6 +88,7 @@
    "utf-8",                     /* we now have a function to decode this */
    NULL
 };
+#endif /* USE_ICONV */
 
 #ifndef SLRNPULL_CODE
 static char *Char_Set;
@@ -120,6 +136,7 @@
 
 int slrn_set_compatible_charsets (char *charsets)
 {
+#ifndef USE_ICONV
    static char* buf;
    char *p;
    char **pp;
@@ -166,10 +183,12 @@
    
    *pp = NULL;
    
+#endif /* USE_ICONV */
    return 0;
 }
 #endif /* NOT SLRNPULL_CODE */
 
+#ifndef USE_ICONV
 static char *_find_compatible_charset (char **compat_charset, char *cs,
                                       unsigned int len)
 {
@@ -187,9 +206,14 @@
      }
    return NULL;
 }
+#endif /* USE_RECOEE */
 
 static char *find_compatible_charset (char *cs, unsigned int len)
 {
+#ifdef USE_ICONV
+   return slrn_strnmalloc (cs, len, 1);
+#else /* USE_ICONV */
+   
    char *retval;
    
    if ((NULL == (retval = _find_compatible_charset (Compatible_Charsets, cs,
@@ -198,6 +222,7 @@
      retval = _find_compatible_charset (Custom_Compatible_Charsets, cs, len);
    
    return retval;
+#endif /* USE_ICONV */
 }
 
 #ifndef SLRNPULL_CODE
@@ -291,13 +316,18 @@
             len = b - charset;
             
             Char_Set = find_compatible_charset (charset, len);
-            return 0;
+            goto END; /* EVIL */
          }
        line = line->next;
      }
    while ((line != NULL)
          && (line->flags & HEADER_LINE)
          && ((*(b = line->buf) == ' ') || (*b == '\t')));
+
+END:
+#ifdef USE_ICONV
+   a->charset = slrn_strmalloc (Char_Set, 1);
+#endif
    
    return 0;
 }
@@ -413,6 +443,7 @@
    return dest;
 }
 
+#ifndef USE_ICONV
 static char *utf_to_unicode (int *out, char *in, char *srcmax)
 {
    int mask = 0;
@@ -495,15 +526,21 @@
    
    return dest;
 }
+#endif /* USE_ICONV */
 
-int slrn_rfc1522_decode_string (char *s)
+int slrn_rfc1522_decode_string (char **str_ptr)
 {
+   char *s = *str_ptr;
    char *s1, *s2, ch;
    char *charset, method, *txt;
    char *after_last_encoded_word;
    char *after_whitespace;
    unsigned int count;
    unsigned int len;
+#ifdef USE_ICONV
+   char *buff, *begin_of_encoded_part, *new_str;
+   char *output;
+#endif
 
    count = 0;
    after_whitespace = NULL;
@@ -512,10 +549,14 @@
 /* Even if some user agents still send raw 8bit, it is safe to call
  * decode_utf8() -- if it finds 8bit chars that are not valid UTF-8, it
  * will set ch to 1 and we can leave the line untouched. */
-#if SLANG_VERSION >= 20000
+#ifdef USE_ICONV
+   output = slrn_safe_strmalloc ( *str_ptr );
+   s = output;
+#else
+# if SLANG_VERSION >= 20000
    if (Slrn_UTF8_Mode == 0)
      {
-#endif
+# endif
    len = strlen (s);
    s1 = slrn_safe_malloc(len + 1);
    
@@ -525,9 +566,10 @@
    if (ch == 0)
      strcpy (s, s1); /* safe */
    slrn_free (s1);
-#if SLANG_VERSION >= 20000
+# if SLANG_VERSION >= 20000
      }
-#endif
+# endif
+#endif /* USE_ICONV */
 
    while (1)
      {
@@ -536,6 +578,9 @@
        if (s == NULL) break;
        
        s1 = s;
+#ifdef USE_ICONV
+        begin_of_encoded_part = s1;
+#endif
        charset = s = s1 + 2;
        while (((ch = *s) != 0)
               && (ch != '?') && (ch != ' ') && (ch != '\t') && (ch != '\n'))
@@ -592,17 +637,67 @@
        /* Note: these functions return a pointer to the END of the decoded
         * text.
         */
+
+#ifdef USE_ICONV
+        /* decoded stuff is always shorter than encoded, so this size 
+         * is safe */
+        /* TODO: I don't think this is always true, specifically consider 
+         * UTF8 encoded 4-byte characters */
+        //buff = (char *) slrn_safe_malloc( strlen(txt) + 10 );
+        len = strlen(txt) + 10;
+        buff = (char *) calloc( len, sizeof(char) );
+        s1 = buff;
+#endif
+    
        s2 = s1;
        
        if (method == 'B')
          s1 = decode_base64 (s1, txt, s);
-       else s1 = decode_quoted_printable (s1, txt, s, 1, 0);
-       
+       else 
+          s1 = decode_quoted_printable (s1, txt, s, 1, 0);
+
+#ifdef USE_ICONV
+        /* ok, now the decoded string is in buff, now translate it */
+       slrn_chmap_translate_string( charset, Slrn_Charset, &buff );
+
+        /* now we have to improvise a bit, because the translated string 
+         * could, in principle be longer than the space that's available in
+         * the original string. 
+         * So, we allocate a _new_ string to replace it, and copy everything 
+         * in there */
+        /* skip the final '?=', if the string doesn't end prematurely */
+        if (*s!='\0' && *(s+1)!='\0') s+=2; 
+        len = begin_of_encoded_part - output  /* part that is done already */
+              + strlen (buff)  /* part we just translated */
+              + strlen (s) /* part that's yet to be translated */
+              + 10; /* to be on the save side */
+        new_str = (char *) slrn_safe_malloc( len * sizeof(char) );
+        s1 = new_str;
+        memcpy (s1, output, begin_of_encoded_part - output); /* old part */
+        s1 += begin_of_encoded_part - output;
+        memcpy (s1, buff, strlen (buff)); /* current part */
+        s1 += strlen (buff);
+        memcpy (s1, s, strlen (s) + 1 ); /* todo part, including final \0 */
+
+        /* now free the old string and set it to the new one */
+        memset(output, 'x', strlen(output));
+        slrn_free (output);
+        output = new_str;
+
+        /* and free the buffer */
+        slrn_free(buff);
+        buff = NULL;
+
+        /* set s to the position where we need to continue on the next 
+         * iteration */
+        s = s1;
+        
+#else /* USE_ICONV */
        if ((slrn_case_strncmp((unsigned char *)"utf-8",
                              (unsigned char *)charset, 5) == 0)
-#if SLANG_VERSION >= 20000
+# if SLANG_VERSION >= 20000
            && (Slrn_UTF8_Mode == 0)
-#endif
+# endif
            )
          s1 = decode_utf8 (s2, s2, s1, NULL);
        
@@ -611,6 +706,7 @@
        s = s1;                        /* start from here next loop */
        while ((ch = *s2++) != 0) *s1++ = ch;
        *s1 = 0;
+#endif
        
        count++;
        
@@ -618,6 +714,12 @@
        s = slrn_skip_whitespace (s);
        after_whitespace = s;
      }
+
+#ifdef USE_ICONV
+   // slrn_free( *str_ptr );
+   *str_ptr = output;
+#endif
+   
    return count;
 }
 
@@ -627,6 +729,14 @@
 static void rfc1522_decode_headers (Slrn_Article_Type *a)
 {
    Slrn_Article_Line_Type *line;
+
+#ifdef USE_ICONV
+   /* make sure we have a charset available */
+   if (a->charset==NULL)
+   {
+       a->charset = slrn_safe_strmalloc(ICONV_DEFAULT_CHARSET);
+   }
+#endif /* USE_ICONV */
    
    if (a == NULL)
      return;
@@ -638,12 +748,26 @@
        if (slrn_case_strncmp ((unsigned char *)line->buf,
                               (unsigned char *)"Newsgroups:", 11) &&
            slrn_case_strncmp ((unsigned char *)line->buf,
-                              (unsigned char *)"Followup-To:", 12) &&
-           slrn_rfc1522_decode_string (line->buf))
-         {
-            a->is_modified = 1;
-            a->mime_was_modified = 1;
-         }
+                              (unsigned char *)"Followup-To:", 12)
+           )
+       {
+          /* ok, some news client (Outlook Express *sigh*) just put
+           * unencoded latin1/9/window1252 chars in their headers.  Try to
+           * decode this */
+          if (slrn_chmap_translate_string(a->charset , Slrn_Charset,
+                &(line->buf)))
+          {
+            a->is_modified = 1;
+            a->mime_was_modified = 1;
+          }
+
+          /* now do the usual rfc 1522 decoding */
+         if (slrn_rfc1522_decode_string (&(line->buf)))
+          {
+            a->is_modified = 1;
+            a->mime_was_modified = 1;
+          }
+       }
        line = line->next;
      }
 }
@@ -845,6 +969,7 @@
      }
 }
 
+#ifndef USE_ICONV
 static void decode_mime_utf8 (Slrn_Article_Type *a)
 {
    Slrn_Article_Line_Type *line;
@@ -879,6 +1004,7 @@
        line = line->next;
      }
 }
+#endif /* USE_ICONV */
 
 void slrn_mime_article_init (Slrn_Article_Type *a)
 {
@@ -894,8 +1020,6 @@
 
    a->mime_was_parsed = 1;            /* or will be */
    
-   rfc1522_decode_headers (a);
-
 /* Is there a reason to use the following line? */
 /*   if (NULL == find_header_line (a, "Mime-Version:")) return;*/
    if ((-1 == parse_content_type_line (a))
@@ -904,6 +1028,8 @@
        a->mime_needs_metamail = 1;
        return;
      }
+
+   rfc1522_decode_headers (a);
    
    switch (Encoding_Method)
      {
@@ -926,14 +1052,16 @@
        return;
      }
    
+#ifndef USE_ICONV
    if ((a->mime_needs_metamail == 0) &&
-#if SLANG_VERSION >= 20000
+# if SLANG_VERSION >= 20000
        (Slrn_UTF8_Mode == 0) &&
-#endif
+# endif
        (Char_Set != NULL) &&
        (slrn_case_strncmp((unsigned char *)"utf-8",
                          (unsigned char *)Char_Set, 5) == 0))
      decode_mime_utf8 (a);
+#endif /* USE_ICONV */
 }
 
 #ifndef MAXPATHLEN
@@ -1525,6 +1653,10 @@
    if (Mime_Posting_Charset == NULL)
      Mime_Posting_Charset = "us-ascii";
 
+   /* TODO: check that a charset header isn't already present */
+   /* so: (1) extract possible charset header and use it to override 
+    * Mime_Posting_Charset here; (2) remove possible duplicate headers 
+    * that we are going to add; (3) add headers as below */
    switch (Mime_Posting_Encoding)
      {
       default:
diff -Naur slrn-0.9.8.1pl1.eerst/src/mime.h slrn-0.9.8.1pl1/src/mime.h
--- slrn-0.9.8.1pl1.eerst/src/mime.h    2006-03-31 18:03:56.000000000 +0200
+++ slrn-0.9.8.1pl1/src/mime.h  2006-03-31 19:14:46.000000000 +0200
@@ -1,6 +1,11 @@
 #ifndef _SLRN_MIME_H
 #define _SLRN_MIME_H
 
+/* don't use recode for slrnpull */
+#if defined(SLRNPULL_CODE) && defined(USE_ICONV)
+# undef USE_ICONV
+#endif
+
 #include "vfile.h"
 
 extern int Slrn_Use_Mime;
@@ -11,7 +16,7 @@
 
 # if SLRN_HAS_MIME /* rest of file in this if */
 extern int slrn_set_compatible_charsets (char *);
-extern int slrn_rfc1522_decode_string (char *);
+extern int slrn_rfc1522_decode_string (char **);
 
 extern VFILE *slrn_mime_encode (VFILE *);
 extern void slrn_mime_header_encode (char *, unsigned int);
diff -Naur slrn-0.9.8.1pl1.eerst/src/slrn.c slrn-0.9.8.1pl1/src/slrn.c
--- slrn-0.9.8.1pl1.eerst/src/slrn.c    2006-03-31 18:03:56.000000000 +0200
+++ slrn-0.9.8.1pl1/src/slrn.c  2006-04-03 23:08:05.000000000 +0200
@@ -107,8 +107,15 @@
 # include <windows.h>
 #endif
 
+/* don't use recode for slrnpull */
+#if defined(SLRNPULL_CODE) && defined(USE_ICONV)
+# undef USE_ICONV
+#endif
+
+
 /*}}}*/
 
+
 /*{{{ Global Variables */
 
 #if SLANG_VERSION >= 20000
@@ -1219,7 +1226,7 @@
    if (Slrn_Post_Id == 0) Slrn_Post_Id = Slrn_Default_Post_Obj;
    if (no_new_groups) Slrn_Check_New_Groups = 0;
 
-#if SLRN_HAS_CHARACTER_MAP
+#if SLRN_HAS_CHARACTER_MAP || defined(USE_ICONV)
    if (-1 == slrn_set_charset (Slrn_Charset))
      {
        slrn_chmap_show_supported ();
@@ -1227,10 +1234,13 @@
      }
 #endif
 
-#if SLRN_HAS_MIME
+#ifdef USE_ICONV
+   Slrn_Mime_Display_Charset = slrn_safe_strmalloc (Slrn_Charset);
+#else /* USE_ICONV */
+# if SLRN_HAS_MIME
    if (NULL == Slrn_Mime_Display_Charset)
-     {
-# if SLRN_HAS_CHARACTER_MAP
+   {
+#  if SLRN_HAS_CHARACTER_MAP
        if (NULL != Slrn_Charset)
          {
             if (0 == slrn_case_strcmp ((unsigned char *)Slrn_Charset,
@@ -1247,10 +1257,11 @@
               Slrn_Mime_Display_Charset = slrn_safe_strmalloc ("iso-8859-7");
          }
        if (NULL == Slrn_Mime_Display_Charset)
-# endif
+#  endif
          Slrn_Mime_Display_Charset = slrn_safe_strmalloc ("iso-8859-1");
+# endif
      }
-#endif
+#endif /* USE_ICONV */
 
 #ifdef SIGINT
    if (Slrn_TT_Initialized == 0)
diff -Naur slrn-0.9.8.1pl1.eerst/src/slrnpull.c slrn-0.9.8.1pl1/src/slrnpull.c
--- slrn-0.9.8.1pl1.eerst/src/slrnpull.c        2006-03-31 18:03:56.000000000 
+0200
+++ slrn-0.9.8.1pl1/src/slrnpull.c      2006-03-31 19:14:46.000000000 +0200
@@ -1335,8 +1335,8 @@
    h.from = slrn_safe_strmalloc (xov->from);
    if (Slrn_Use_Mime)
      {
-       slrn_rfc1522_decode_string (h.subject);
-       slrn_rfc1522_decode_string (h.from);
+       slrn_rfc1522_decode_string (&(h.subject));
+       slrn_rfc1522_decode_string (&(h.from));
      }
 #endif
    
diff -Naur slrn-0.9.8.1pl1.eerst/src/startup.c slrn-0.9.8.1pl1/src/startup.c
--- slrn-0.9.8.1pl1.eerst/src/startup.c 2006-03-31 18:03:56.000000000 +0200
+++ slrn-0.9.8.1pl1/src/startup.c       2006-03-31 19:14:46.000000000 +0200
@@ -61,6 +61,13 @@
 #ifdef VMS
 # include "vms.h"
 #endif
+
+/* don't use recode for slrnpull */
+#if defined(SLRNPULL_CODE) && defined(USE_ICONV)
+# undef USE_ICONV
+#endif
+
+
 /*}}}*/
 
 /*{{{ Forward Function Declarations */
@@ -692,13 +699,15 @@
      },
      
 #if SLRN_HAS_MIME
+# ifndef USE_ICONV /* this is fetched from the current locale */
      {"mime_charset", &Slrn_Mime_Display_Charset},
+# endif /* USE_ICONV */
      {"metamail_command", &Slrn_MetaMail_Cmd},
 #else
      {"mime_charset", NULL},
      {"metamail_command", NULL},
 #endif
-#if SLRN_HAS_CHARACTER_MAP
+#if SLRN_HAS_CHARACTER_MAP && !defined(USE_ICONV)
      {"charset", &Slrn_Charset},
 #else
      {"charset", NULL},
diff -Naur slrn-0.9.8.1pl1.eerst/src/xover.c slrn-0.9.8.1pl1/src/xover.c
--- slrn-0.9.8.1pl1.eerst/src/xover.c   2006-03-31 18:03:56.000000000 +0200
+++ slrn-0.9.8.1pl1/src/xover.c 2006-03-31 19:41:04.000000000 +0200
@@ -155,7 +155,7 @@
                                     (unsigned char *)"Newsgroups") &&
                   slrn_case_strcmp ((unsigned char *)h,
                                     (unsigned char *)"Followup-To"))
-                slrn_rfc1522_decode_string (colon);
+                slrn_rfc1522_decode_string (&colon);
 #endif
               addh->value = colon;
               break;

Reply via email to