--- gnupg-1.4.0/util/strgutil.c 2004-11-17 15:50:58.000000000 +0000 +++ /tmp/dpep.GtChya/gnupg-1.4.0/util/strgutil.c 2005-02-05 00:53:22.921264222 +0000 @@ -1,6 +1,6 @@ /* strgutil.c - string utilities * Copyright (C) 1994, 1998, 1999, 2000, 2001, - * 2003 Free Software Foundation, Inc. + * 2003, 2004, 2005 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -144,6 +144,8 @@ { log_info (_("error loading `%s': %s\n"), "iconv.dll", dlerror ()); + log_info(_("please see http://www.gnupg.org/download/iconv.html " + "for more information\n")); iconv_open = NULL; iconv = NULL; iconv_close = NULL; @@ -451,10 +453,33 @@ handle_iconv_error (const char *to, const char *from, int use_fallback) { if (errno == EINVAL) - log_error (_("conversion from `%s' to `%s' not available\n"), - from, to); + { + static int shown1, shown2; + int x; + + if (to && !strcmp (to, "utf-8")) + { + x = shown1; + shown1 = 1; + } + else + { + x = shown2; + shown2 = 1; + } + + if (!x) + log_info (_("conversion from `%s' to `%s' not available\n"), + from, to); + } else - log_error (_("iconv_open failed: %s\n"), strerror (errno)); + { + static int shown; + + if (!shown) + log_info (_("iconv_open failed: %s\n"), strerror (errno)); + shown = 1; + } if (use_fallback) { @@ -479,28 +504,78 @@ if (!newset) { #ifdef _WIN32 static char codepage[30]; + unsigned int cpno; + const char *aliases; /* We are a console program thus we need to use the - GetConsoleOutputCP fucntion and not the the GetACP which + GetConsoleOutputCP function and not the the GetACP which would give the codepage for a GUI program. Note this is not a bulletproof detection because GetConsoleCP might - retrun a different one for console input. Not sure how to - cope with that. */ - sprintf (codepage, "CP%u", (unsigned int)GetConsoleOutputCP ()); - /* If it is the Windows name for Latin-1 we use the standard - name instead to avoid loading of iconv.dll. Unfortunately - it is often CP850 and we don't have a custom translation - for it. */ - if (!strcmp (codepage, "CP1252")) - newset = "iso-8859-1"; - else - newset = codepage; + return a different one for console input. Not sure how to + cope with that. If the console Code page is not known we + fall back to the system code page. */ + cpno = GetConsoleOutputCP (); + if (!cpno) + cpno = GetACP (); + sprintf (codepage, "CP%u", cpno ); + /* Resolve alias. We use a long string string and not the + usual array to optimize if the code is taken to a DSO. + Taken from libiconv 1.9.2. */ + newset = codepage; + for (aliases = ("CP936" "\0" "GBK" "\0" + "CP1361" "\0" "JOHAB" "\0" + "CP20127" "\0" "ASCII" "\0" + "CP20866" "\0" "KOI8-R" "\0" + "CP21866" "\0" "KOI8-RU" "\0" + "CP28591" "\0" "ISO-8859-1" "\0" + "CP28592" "\0" "ISO-8859-2" "\0" + "CP28593" "\0" "ISO-8859-3" "\0" + "CP28594" "\0" "ISO-8859-4" "\0" + "CP28595" "\0" "ISO-8859-5" "\0" + "CP28596" "\0" "ISO-8859-6" "\0" + "CP28597" "\0" "ISO-8859-7" "\0" + "CP28598" "\0" "ISO-8859-8" "\0" + "CP28599" "\0" "ISO-8859-9" "\0" + "CP28605" "\0" "ISO-8859-15" "\0"); + *aliases; + aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1) + { + if (!strcmp (codepage, aliases) ||(*aliases == '*' && !aliases[1])) + { + newset = aliases + strlen (aliases) + 1; + break; + } + } + #else #ifdef HAVE_LANGINFO_CODESET newset = nl_langinfo (CODESET); -#else - newset = "iso-8859-1"; -#endif +#else /* !HAVE_LANGINFO_CODESET */ + /* Try to get the used charset from environment variables. */ + static char codepage[30]; + const char *lc, *dot, *mod; + + strcpy (codepage, "iso-8859-1"); + lc = getenv ("LC_ALL"); + if (!lc || !*lc) { + lc = getenv ("LC_CTYPE"); + if (!lc || !*lc) + lc = getenv ("LANG"); + } + if (lc && *lc) { + dot = strchr (lc, '.'); + if (dot) { + mod = strchr (++dot, '@'); + if (!mod) + mod = dot + strlen (dot); + if (mod - dot < sizeof codepage && dot != mod) { + memcpy (codepage, dot, mod - dot); + codepage [mod - dot] = 0; + } + } + } + newset = codepage; +#endif /* !HAVE_LANGINFO_CODESET */ #endif } @@ -511,9 +586,18 @@ newset++; } + /* Note that we silently assume that plain ASCII is actually meant + as Latin-1. This makes sense because many Unix system don't + have their locale set up properly and thus would get annoying + error messages and we have to handle all the "bug" + reports. Latin-1 has always been the character set used for 8 + bit characters on Unix systems. */ if( !*newset || !ascii_strcasecmp (newset, "8859-1" ) - || !ascii_strcasecmp (newset, "8859-15" ) ) { + || !ascii_strcasecmp (newset, "646" ) + || !ascii_strcasecmp (newset, "ASCII" ) + || !ascii_strcasecmp (newset, "ANSI_X3.4-1968" ) + ) { active_charset_name = "iso-8859-1"; no_translation = 0; active_charset = NULL; @@ -645,8 +729,12 @@ if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes, &outptr, &outbytes) == (size_t)-1) { - log_error (_("conversion from `%s' to `%s' failed: %s\n"), - active_charset_name, "utf-8", strerror (errno)); + static int shown; + + if (!shown) + log_info (_("conversion from `%s' to `%s' failed: %s\n"), + active_charset_name, "utf-8", strerror (errno)); + shown = 1; /* We don't do any conversion at all but use the strings as is. */ strcpy (buffer, string); } @@ -919,8 +1007,12 @@ outbuf = outptr = m_alloc (outbytes); if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes, &outptr, &outbytes) == (size_t)-1) { - log_error (_("conversion from `%s' to `%s' failed: %s\n"), - "utf-8", active_charset_name, strerror (errno)); + static int shown; + + if (!shown) + log_info (_("conversion from `%s' to `%s' failed: %s\n"), + "utf-8", active_charset_name, strerror (errno)); + shown = 1; /* Didn't worked out. Temporary disable the use of * iconv and fall back to our old code. */ m_free (buffer);