1N/A/*
1N/A * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
1N/A */
1N/A
1N/A/*
1N/A * The contents of this file are subject to the Netscape Public
1N/A * License Version 1.1 (the "License"); you may not use this file
1N/A * except in compliance with the License. You may obtain a copy of
1N/A * the License at http://www.mozilla.org/NPL/
1N/A *
1N/A * Software distributed under the License is distributed on an "AS
1N/A * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
1N/A * implied. See the License for the specific language governing
1N/A * rights and limitations under the License.
1N/A *
1N/A * The Original Code is Mozilla Communicator client code, released
1N/A * March 31, 1998.
1N/A *
1N/A * The Initial Developer of the Original Code is Netscape
1N/A * Communications Corporation. Portions created by Netscape are
1N/A * Copyright (C) 1998-1999 Netscape Communications Corporation. All
1N/A * Rights Reserved.
1N/A *
1N/A * Contributor(s):
1N/A */
1N/A
1N/A#include <stdio.h>
1N/A#include <stdlib.h>
1N/A#include <string.h>
1N/A#include <locale.h>
1N/A#include <ctype.h>
1N/A
1N/A#ifndef HAVE_LIBICU
1N/A
1N/A#ifdef SOLARIS_LDAP_CMD
1N/A#include <errno.h>
1N/A#include <langinfo.h>
1N/A#include <iconv.h>
1N/A#endif
1N/A
1N/A#ifdef __cplusplus
1N/Aextern "C" {
1N/A#endif
1N/A
1N/Aextern char *ldaptool_charset;
1N/Achar *ldaptool_convdir = NULL;
1N/Astatic int charsetset = 0;
1N/Achar *ldaptool_local2UTF8( const char *src );
1N/A
1N/A#ifdef SOLARIS_LDAP_CMD
1N/Astatic char *ldaptool_convert( const char *src, const char *fcode,
1N/A const char *tcode);
1N/Achar *ldaptool_UTF82local( const char *src );
1N/A#endif /* SOLARIS_LDAP_CMD */
1N/A
1N/A#ifdef SOLARIS_LDAP_CMD
1N/A/*
1N/A * ICU version always returns string, unless strdup fails.
1N/A * As in ICU version, in case of error strdup(src)
1N/A * Usually strdup(src) will be ASCII and legal anyways.
1N/A */
1N/A
1N/Astatic char *
1N/Aldaptool_convert( const char *src, const char *fcode,
1N/A const char *tcode) {
1N/A char *dest, *tptr, *tmp;
1N/A char *fptr;
1N/A iconv_t cd;
1N/A size_t ileft, oleft, ret, size;
1N/A
1N/A if (src == NULL)
1N/A return (NULL);
1N/A
1N/A if (fcode == NULL || tcode == NULL)
1N/A return (strdup(src));
1N/A
1N/A if (strcasecmp(fcode, tcode) == 0)
1N/A return (strdup(src));
1N/A
1N/A if ((cd = iconv_open(tcode, fcode)) == (iconv_t)-1) {
1N/A /* conversion table not available */
1N/A return (strdup(src));
1N/A }
1N/A
1N/A ileft = strlen(src);
1N/A oleft = 2 * ileft;
1N/A size = oleft;
1N/A ret = -1;
1N/A if ((dest = (char *)malloc(size)) == NULL) {
1N/A (void) iconv_close(cd);
1N/A /* maybe sizeof strlen(src) memory still exists */
1N/A return (strdup(src));
1N/A }
1N/A tptr = dest;
1N/A fptr = (char *)src;
1N/A
1N/A for (;;) {
1N/A ret = iconv(cd, &fptr, &ileft, &tptr, &oleft);
1N/A
1N/A if (ret != (size_t)-1) {
1N/A /*
1N/A * Success. Place 'cd' into its initial shift
1N/A * state before returning.
1N/A */
1N/A if (fptr == NULL) /* already in initial state */
1N/A break;
1N/A fptr = NULL;
1N/A ileft = 0;
1N/A continue;
1N/A } if (errno == E2BIG) {
1N/A /*
1N/A * Lack of space in output buffer.
1N/A * Hence double the size and retry.
1N/A * But before calling iconv(), oleft
1N/A * and tptr have to re-adjusted, so that
1N/A * iconv() doesn't overwrite the data
1N/A * which has already been converted.
1N/A */
1N/A oleft += size;
1N/A size *= 2;
1N/A if ((tmp = (char *) realloc(dest, size)) == NULL)
1N/A break;
1N/A tptr = tmp + (tptr - dest);
1N/A dest = tmp;
1N/A continue;
1N/A } else {
1N/A /* Other errors */
1N/A break;
1N/A }
1N/A }
1N/A
1N/A if (dest != NULL) {
1N/A if (ret == -1) {
1N/A /* Free malloc'ed memory on failure */
1N/A free(dest);
1N/A dest = NULL;
1N/A } else if (oleft > 0) {
1N/A /* NULL terminate the return value */
1N/A *(dest + (size - oleft)) = '\0';
1N/A } else {
1N/A /* realloc one more byte and NULL terminate */
1N/A if ((tmp = (char *) realloc(dest, size + 1)) == NULL) {
1N/A free(dest);
1N/A dest = NULL;
1N/A } else {
1N/A *(dest + size) = '\0';
1N/A }
1N/A }
1N/A }
1N/A
1N/A (void) iconv_close(cd);
1N/A if (dest == NULL) {
1N/A /* last chance in case some other failure along the way occurs */
1N/A return (strdup(src));
1N/A }
1N/A return (dest);
1N/A}
1N/A
1N/Achar *
1N/Aldaptool_UTF82local( const char *src )
1N/A{
1N/A char *to_code;
1N/A if ((to_code = nl_langinfo(CODESET)) == NULL)
1N/A return (strdup(src));
1N/A return (ldaptool_convert(src, "UTF-8", (const char *)to_code));
1N/A}
1N/A#endif /* SOLARIS_LDAP_CMD */
1N/A
1N/Achar *
1N/Aldaptool_local2UTF8( const char *src )
1N/A{
1N/A#ifdef SOLARIS_LDAP_CMD
1N/A char *from_code;
1N/A if ((from_code = nl_langinfo(CODESET)) == NULL)
1N/A return (strdup(src));
1N/A return (ldaptool_convert(src, (const char *)from_code, "UTF-8"));
1N/A#else
1N/A char *utf8;
1N/A charsetset = 0;
1N/A if (src == NULL)
1N/A {
1N/A return NULL;
1N/A }
1N/A utf8 = strdup(src);
1N/A return ( utf8 );
1N/A#endif /* SOLARIS_LDAP_CMD */
1N/A}
1N/A
1N/A#else /* HAVE_LIBICU */
1N/A
1N/A#include "unicode/utypes.h"
1N/A#include "unicode/ucnv.h"
1N/A
1N/A#define NSPR20
1N/A
1N/A#ifdef XP_WIN32
1N/A#define VC_EXTRALEAN
1N/A#include <afxwin.h>
1N/A#include <winnls.h>
1N/A#endif
1N/A
1N/Aextern char *ldaptool_charset;
1N/Astatic int charsetset = 0;
1N/A
1N/Aextern "C" {
1N/Achar *ldaptool_convdir = NULL;
1N/Achar *ldaptool_local2UTF8( const char * );
1N/A}
1N/A
1N/A#ifndef XP_WIN32
1N/Achar * GetNormalizedLocaleName(void);
1N/A
1N/A
1N/Achar *
1N/AGetNormalizedLocaleName(void)
1N/A{
1N/A#ifdef _HPUX_SOURCE
1N/A
1N/A int len;
1N/A char *locale;
1N/A
1N/A locale = setlocale(LC_CTYPE, "");
1N/A if (locale && *locale) {
1N/A len = strlen(locale);
1N/A } else {
1N/A locale = "C";
1N/A len = 1;
1N/A }
1N/A
1N/A if ((!strncmp(locale, "/\x03:", 3)) &&
1N/A (!strcmp(&locale[len - 2], ";/"))) {
1N/A locale += 3;
1N/A len -= 5;
1N/A }
1N/A
1N/A locale = strdup(locale);
1N/A if (locale) {
1N/A locale[len] = 0;
1N/A }
1N/A
1N/A return locale;
1N/A
1N/A#else
1N/A
1N/A char *locale;
1N/A
1N/A locale = setlocale(LC_CTYPE, "");
1N/A if (locale && *locale) {
1N/A return strdup(locale);
1N/A }
1N/A
1N/A return strdup("C");
1N/A
1N/A#endif
1N/A}
1N/A
1N/A#if defined(IRIX)
1N/Aconst char *CHARCONVTABLE[] =
1N/A{
1N/A"! This table maps the host's locale names to IANA charsets",
1N/A"!",
1N/A"C: ISO_8859-1:1987",
1N/A"cs: ISO_8859-2:1987",
1N/A"da: ISO_8859-1:1987",
1N/A"de: ISO_8859-1:1987",
1N/A"de_AT: ISO_8859-1:1987",
1N/A"de_CH: ISO_8859-1:1987",
1N/A"en: ISO_8859-1:1987",
1N/A"en_AU: ISO_8859-1:1987",
1N/A"en_CA: ISO_8859-1:1987",
1N/A"en_TH: ISO_8859-1:1987",
1N/A"en_US: ISO_8859-1:1987",
1N/A"es: ISO_8859-1:1987",
1N/A"fi: ISO_8859-1:1987",
1N/A"fr: ISO_8859-1:1987",
1N/A"fr_BE: ISO_8859-1:1987",
1N/A"fr_CA: ISO_8859-1:1987",
1N/A"fr_CH: ISO_8859-1:1987",
1N/A"is: ISO_8859-1:1987",
1N/A"it: ISO_8859-1:1987",
1N/A"it_CH: ISO_8859-1:1987",
1N/A"ja_JP.EUC: Extended_UNIX_Code_Packed_Format_for_Japanese",
1N/A"ko_KR.euc: EUC-KR",
1N/A"nl: ISO_8859-1:1987",
1N/A"nl_BE: ISO_8859-1:1987",
1N/A"no: ISO_8859-1:1987",
1N/A"pl: ISO_8859-2:1987",
1N/A"pt: ISO_8859-1:1987",
1N/A"sh: ISO_8859-2:1987",
1N/A"sk: ISO_8859-2:1987",
1N/A"sv: ISO_8859-1:1987",
1N/A"zh_CN.ugb: GB2312",
1N/A"zh_TW.ucns: cns11643_1",
1N/ANULL
1N/A};
1N/A#elif defined(SOLARIS)
1N/Aconst char *CHARCONVTABLE[] =
1N/A{
1N/A"! This table maps the host's locale names to IANA charsets",
1N/A"!",
1N/A"C: ISO_8859-1:1987",
1N/A"ja: Extended_UNIX_Code_Packed_Format_for_Japanese",
1N/A"ja_JP.EUC: Extended_UNIX_Code_Packed_Format_for_Japanese",
1N/A"ja_JP.PCK: Shift_JIS",
1N/A"en: ISO_8859-1:1987",
1N/A"en_AU: ISO_8859-1:1987",
1N/A"en_CA: ISO_8859-1:1987",
1N/A"en_UK: ISO_8859-1:1987",
1N/A"en_US: ISO_8859-1:1987",
1N/A"es: ISO_8859-1:1987",
1N/A"es_AR: ISO_8859-1:1987",
1N/A"es_BO: ISO_8859-1:1987",
1N/A"es_CL: ISO_8859-1:1987",
1N/A"es_CO: ISO_8859-1:1987",
1N/A"es_CR: ISO_8859-1:1987",
1N/A"es_EC: ISO_8859-1:1987",
1N/A"es_GT: ISO_8859-1:1987",
1N/A"es_MX: ISO_8859-1:1987",
1N/A"es_NI: ISO_8859-1:1987",
1N/A"es_PA: ISO_8859-1:1987",
1N/A"es_PE: ISO_8859-1:1987",
1N/A"es_PY: ISO_8859-1:1987",
1N/A"es_SV: ISO_8859-1:1987",
1N/A"es_UY: ISO_8859-1:1987",
1N/A"es_VE: ISO_8859-1:1987",
1N/A"fr: ISO_8859-1:1987",
1N/A"fr_BE: ISO_8859-1:1987",
1N/A"fr_CA: ISO_8859-1:1987",
1N/A"fr_CH: ISO_8859-1:1987",
1N/A"de: ISO_8859-1:1987",
1N/A"de_AT: ISO_8859-1:1987",
1N/A"de_CH: ISO_8859-1:1987",
1N/A"nl: ISO_8859-1:1987",
1N/A"nl_BE: ISO_8859-1:1987",
1N/A"it: ISO_8859-1:1987",
1N/A"sv: ISO_8859-1:1987",
1N/A"no: ISO_8859-1:1987",
1N/A"da: ISO_8859-1:1987",
1N/A"iso_8859_1: ISO_8859-1:1987",
1N/A"japanese: Extended_UNIX_Code_Packed_Format_for_Japanese",
1N/A"ko: EUC-KR",
1N/A"zh: GB2312",
1N/A"zh_TW: cns11643_1",
1N/ANULL
1N/A};
1N/A#elif defined(OSF1)
1N/Aconst char *CHARCONVTABLE[] =
1N/A{
1N/A"! This table maps the host's locale names to IANA charsets",
1N/A"!",
1N/A"C: ISO_8859-1:1987",
1N/A"cs_CZ.ISO8859-2: ISO_8859-2:1987",
1N/A"cs_CZ: ISO_8859-2:1987",
1N/A"da_DK.ISO8859-1: ISO_8859-1:1987",
1N/A"de_CH.ISO8859-1: ISO_8859-1:1987",
1N/A"de_DE.ISO8859-1: ISO_8859-1:1987",
1N/A"en_GB.ISO8859-1: ISO_8859-1:1987",
1N/A"en_US.ISO8859-1: ISO_8859-1:1987",
1N/A"es_ES.ISO8859-1: ISO_8859-1:1987",
1N/A"fi_FI.ISO8859-1: ISO_8859-1:1987",
1N/A"fr_BE.ISO8859-1: ISO_8859-1:1987",
1N/A"fr_CA.ISO8859-1: ISO_8859-1:1987",
1N/A"fr_CH.ISO8859-1: ISO_8859-1:1987",
1N/A"fr_FR.ISO8859-1: ISO_8859-1:1987",
1N/A"hu_HU.ISO8859-2: ISO_8859-2:1987",
1N/A"hu_HU: ISO_8859-2:1987",
1N/A"is_IS.ISO8859-1: ISO_8859-1:1987",
1N/A"it_IT.ISO8859-1: ISO_8859-1:1987",
1N/A"ja_JP.SJIS: Shift_JIS",
1N/A"ja_JP.eucJP: Extended_UNIX_Code_Packed_Format_for_Japanese",
1N/A"ja_JP: Extended_UNIX_Code_Packed_Format_for_Japanese",
1N/A"ko_KR.eucKR: EUC-KR",
1N/A"ko_KR: EUC-KR",
1N/A"nl_BE.ISO8859-1: ISO_8859-1:1987",
1N/A"nl_NL.ISO8859-1: ISO_8859-1:1987",
1N/A"no_NO.ISO8859-1: ISO_8859-1:1987",
1N/A"pl_PL.ISO8859-2: ISO_8859-2:1987",
1N/A"pl_PL: ISO_8859-2:1987",
1N/A"pt_PT.ISO8859-1: ISO_8859-1:1987",
1N/A"sk_SK.ISO8859-2: ISO_8859-2:1987",
1N/A"sk_SK: ISO_8859-2:1987",
1N/A"sv_SE.ISO8859-1: ISO_8859-1:1987",
1N/A"zh_CN: GB2312",
1N/A"zh_HK.big5: Big5",
1N/A"zh_HK.eucTW: cns11643_1",
1N/A"zh_TW.big5: Big5",
1N/A"zh_TW.big5@chuyin: Big5",
1N/A"zh_TW.big5@radical: Big5",
1N/A"zh_TW.big5@stroke: Big5",
1N/A"zh_TW.eucTW: cns11643_1",
1N/A"zh_TW.eucTW@chuyin: cns11643_1",
1N/A"zh_TW.eucTW@radical: cns11643_1",
1N/A"zh_TW.eucTW@stroke: cns11643_1",
1N/A"zh_TW: cns11643_1",
1N/ANULL
1N/A};
1N/A#elif defined(HPUX)
1N/Aconst char *CHARCONVTABLE[] =
1N/A{
1N/A"! This table maps the host's locale names to IANA charsets",
1N/A"!",
1N/A"C: ISO_8859-1:1987",
1N/A"ja_JP: Extended_UNIX_Code_Packed_Format_for_Japanese",
1N/A"ja_JP.SJIS: Shift_JIS",
1N/A"ja_JP.eucJP: Extended_UNIX_Code_Packed_Format_for_Japanese",
1N/A"es_ES: ISO_8859-1:1987",
1N/A"es_ES.iso88591: ISO_8859-1:1987",
1N/A"sv_SE: ISO_8859-1:1987",
1N/A"sv_SE.iso88591: ISO_8859-1:1987",
1N/A"da_DK: ISO_8859-1:1987",
1N/A"da_DK.iso88591: ISO_8859-1:1987",
1N/A"nl_NL: ISO_8859-1:1987",
1N/A"nl_NL.iso88591: ISO_8859-1:1987",
1N/A"en: ISO_8859-1:1987",
1N/A"en_GB: ISO_8859-1:1987",
1N/A"en_GB.iso88591: ISO_8859-1:1987",
1N/A"en_US: ISO_8859-1:1987",
1N/A"en_US.iso88591: ISO_8859-1:1987",
1N/A"fi_FI: ISO_8859-1:1987",
1N/A"fi_FI.iso88591: ISO_8859-1:1987",
1N/A"fr_CA: ISO_8859-1:1987",
1N/A"fr_CA.iso88591: ISO_8859-1:1987",
1N/A"fr_FR: ISO_8859-1:1987",
1N/A"fr_FR.iso88591: ISO_8859-1:1987",
1N/A"de_DE: ISO_8859-1:1987",
1N/A"de_DE.iso88591: ISO_8859-1:1987",
1N/A"is_IS: ISO_8859-1:1987",
1N/A"is_IS.iso88591: ISO_8859-1:1987",
1N/A"it_IT: ISO_8859-1:1987",
1N/A"it_IT.iso88591: ISO_8859-1:1987",
1N/A"no_NO: ISO_8859-1:1987",
1N/A"no_NO.iso88591: ISO_8859-1:1987",
1N/A"pt_PT: ISO_8859-1:1987",
1N/A"pt_PT.iso88591: ISO_8859-1:1987",
1N/A"hu_HU: ISO_8859-2:1987",
1N/A"hu_HU.iso88592: ISO_8859-2:1987",
1N/A"cs_CZ: ISO_8859-2:1987",
1N/A"cs_CZ.iso88592: ISO_8859-2:1987",
1N/A"pl_PL: ISO_8859-2:1987",
1N/A"pl_PL.iso88592: ISO_8859-2:1987",
1N/A"ro_RO: ISO_8859-2:1987",
1N/A"ro_RO.iso88592: ISO_8859-2:1987",
1N/A"hr_HR: ISO_8859-2:1987",
1N/A"hr_HR.iso88592: ISO_8859-2:1987",
1N/A"sk_SK: ISO_8859-2:1987",
1N/A"sk_SK.iso88592: ISO_8859-2:1987",
1N/A"sl_SI: ISO_8859-2:1987",
1N/A"sl_SI.iso88592: ISO_8859-2:1987",
1N/A"american.iso88591: ISO_8859-1:1987",
1N/A"bulgarian: ISO_8859-2:1987",
1N/A"c-french.iso88591: ISO_8859-1:1987",
1N/A"chinese-s: GB2312",
1N/A"chinese-t.big5: Big5",
1N/A"czech: ISO_8859-2:1987",
1N/A"danish.iso88591: ISO_8859-1:1987",
1N/A"dutch.iso88591: ISO_8859-1:1987",
1N/A"english.iso88591: ISO_8859-1:1987",
1N/A"finnish.iso88591: ISO_8859-1:1987",
1N/A"french.iso88591: ISO_8859-1:1987",
1N/A"german.iso88591: ISO_8859-1:1987",
1N/A"hungarian: ISO_8859-2:1987",
1N/A"icelandic.iso88591: ISO_8859-1:1987",
1N/A"italian.iso88591: ISO_8859-1:1987",
1N/A"japanese.euc: Extended_UNIX_Code_Packed_Format_for_Japanese",
1N/A"japanese: Shift_JIS",
1N/A"katakana: Shift_JIS",
1N/A"korean: EUC-KR",
1N/A"norwegian.iso88591: ISO_8859-1:1987",
1N/A"polish: ISO_8859-2:1987",
1N/A"portuguese.iso88591: ISO_8859-1:1987",
1N/A"rumanian: ISO_8859-2:1987",
1N/A"serbocroatian: ISO_8859-2:1987",
1N/A"slovene: ISO_8859-2:1987",
1N/A"spanish.iso88591: ISO_8859-1:1987",
1N/A"swedish.iso88591: ISO_8859-1:1987",
1N/ANULL
1N/A};
1N/A#elif defined(AIX)
1N/Aconst char *CHARCONVTABLE[] =
1N/A{
1N/A"! This table maps the host's locale names to IANA charsets",
1N/A"!",
1N/A"C: ISO_8859-1:1987",
1N/A"En_JP.IBM-932: Shift_JIS",
1N/A"En_JP: Shift_JIS",
1N/A"Ja_JP.IBM-932: Shift_JIS",
1N/A"Ja_JP: Shift_JIS",
1N/A"da_DK.ISO8859-1: ISO_8859-1:1987",
1N/A"da_DK: ISO_8859-1:1987",
1N/A"de_CH.ISO8859-1: ISO_8859-1:1987",
1N/A"de_CH: ISO_8859-1:1987",
1N/A"de_DE.ISO8859-1: ISO_8859-1:1987",
1N/A"de_DE: ISO_8859-1:1987",
1N/A"en_GB.ISO8859-1: ISO_8859-1:1987",
1N/A"en_GB: ISO_8859-1:1987",
1N/A"en_JP.IBM-eucJP: Extended_UNIX_Code_Packed_Format_for_Japanese",
1N/A"en_JP: Extended_UNIX_Code_Packed_Format_for_Japanese",
1N/A"en_KR.IBM-eucKR: EUC-KR",
1N/A"en_KR: EUC-KR",
1N/A"en_TW.IBM-eucTW: cns11643_1",
1N/A"en_TW: cns11643_1",
1N/A"en_US.ISO8859-1: ISO_8859-1:1987",
1N/A"en_US: ISO_8859-1:1987",
1N/A"es_ES.ISO8859-1: ISO_8859-1:1987",
1N/A"es_ES: ISO_8859-1:1987",
1N/A"fi_FI.ISO8859-1: ISO_8859-1:1987",
1N/A"fi_FI: ISO_8859-1:1987",
1N/A"fr_BE.ISO8859-1: ISO_8859-1:1987",
1N/A"fr_BE: ISO_8859-1:1987",
1N/A"fr_CA.ISO8859-1: ISO_8859-1:1987",
1N/A"fr_CA: ISO_8859-1:1987",
1N/A"fr_CH.ISO8859-1: ISO_8859-1:1987",
1N/A"fr_CH: ISO_8859-1:1987",
1N/A"fr_FR.ISO8859-1: ISO_8859-1:1987",
1N/A"fr_FR: ISO_8859-1:1987",
1N/A"is_IS.ISO8859-1: ISO_8859-1:1987",
1N/A"is_IS: ISO_8859-1:1987",
1N/A"it_IT.ISO8859-1: ISO_8859-1:1987",
1N/A"it_IT: ISO_8859-1:1987",
1N/A"ja_JP.IBM-eucJP: Extended_UNIX_Code_Packed_Format_for_Japanese",
1N/A"ja_JP: Extended_UNIX_Code_Packed_Format_for_Japanese",
1N/A"ko_KR.IBM-eucKR: EUC-KR",
1N/A"ko_KR: EUC-KR",
1N/A"nl_BE.ISO8859-1: ISO_8859-1:1987",
1N/A"nl_BE: ISO_8859-1:1987",
1N/A"nl_NL.ISO8859-1: ISO_8859-1:1987",
1N/A"nl_NL: ISO_8859-1:1987",
1N/A"no_NO.ISO8859-1: ISO_8859-1:1987",
1N/A"no_NO: ISO_8859-1:1987",
1N/A"pt_PT.ISO8859-1: ISO_8859-1:1987",
1N/A"pt_PT: ISO_8859-1:1987",
1N/A"sv_SE.ISO8859-1: ISO_8859-1:1987",
1N/A"sv_SE: ISO_8859-1:1987",
1N/A"zh_TW.IBM-eucTW: cns11643_1",
1N/A"zh_TW: cns11643_1",
1N/ANULL
1N/A};
1N/A#else // sunos by default
1N/Aconst char *CHARCONVTABLE[] =
1N/A{
1N/A"! This table maps the host's locale names to IANA charsets",
1N/A"!",
1N/A"C: ISO_8859-1:1987",
1N/A"de: ISO_8859-1:1987",
1N/A"en_US: ISO_8859-1:1987",
1N/A"es: ISO_8859-1:1987",
1N/A"fr: ISO_8859-1:1987",
1N/A"iso_8859_1: ISO_8859-1:1987",
1N/A"it: ISO_8859-1:1987",
1N/A"ja: Extended_UNIX_Code_Packed_Format_for_Japanese",
1N/A"ja_JP.EUC: Extended_UNIX_Code_Packed_Format_for_Japanese",
1N/A"japanese: Extended_UNIX_Code_Packed_Format_for_Japanese",
1N/A"ko: EUC-KR",
1N/A"sv: ISO_8859-1:1987",
1N/A"zh: GB2312",
1N/A"zh_TW: cns11643_1",
1N/ANULL
1N/A};
1N/A#endif
1N/A
1N/A#define BSZ 256
1N/A
1N/Achar *
1N/AGetCharsetFromLocale(char *locale)
1N/A{
1N/A char *tmpcharset = NULL;
1N/A char buf[BSZ];
1N/A char *p;
1N/A const char *line;
1N/A int i=0;
1N/A
1N/A line = CHARCONVTABLE[i];
1N/A while (line != NULL)
1N/A {
1N/A if (*line == 0)
1N/A {
1N/A break;
1N/A }
1N/A
1N/A strcpy(buf, line);
1N/A line = CHARCONVTABLE[++i];
1N/A
1N/A if (strlen(buf) == 0 || buf[0] == '!')
1N/A {
1N/A continue;
1N/A }
1N/A p = strchr(buf, ':');
1N/A if (p == NULL)
1N/A {
1N/A tmpcharset = NULL;
1N/A break;
1N/A }
1N/A *p = 0;
1N/A if (strcmp(buf, locale) == 0) {
1N/A while (*++p == ' ' || *p == '\t')
1N/A ;
1N/A if (isalpha(*p)) {
1N/A tmpcharset = strdup(p);
1N/A } else
1N/A tmpcharset = NULL;
1N/A
1N/A break;
1N/A }
1N/A }
1N/A return tmpcharset;
1N/A}
1N/A
1N/A#endif /* Not defined XP_WIN32 */
1N/A
1N/A#ifdef XP_WIN32
1N/Achar *_convertor(const char *instr, int bFromUTF8)
1N/A{
1N/A char *outstr = NULL;
1N/A int inlen, wclen, outlen;
1N/A LPWSTR wcstr;
1N/A
1N/A if (instr == NULL)
1N/A return NULL;
1N/A
1N/A if ((inlen = strlen(instr)) <= 0)
1N/A return NULL;
1N/A
1N/A /* output never becomes longer than input,
1N/A * thus we don't have to ask for the length
1N/A */
1N/A wcstr = (LPWSTR) malloc( sizeof( WCHAR ) * (inlen+1) );
1N/A if (!wcstr)
1N/A return NULL;
1N/A
1N/A wclen = MultiByteToWideChar(bFromUTF8 ? CP_UTF8 : CP_ACP, 0, instr,
1N/A inlen, wcstr, inlen);
1N/A outlen = WideCharToMultiByte(bFromUTF8 ? CP_ACP : CP_UTF8, 0, wcstr,
1N/A wclen, NULL, 0, NULL, NULL);
1N/A
1N/A if (outlen > 0) {
1N/A outstr = (char *) malloc(outlen + 2);
1N/A outlen = WideCharToMultiByte(bFromUTF8 ? CP_ACP : CP_UTF8, 0, wcstr,
1N/A wclen, outstr, outlen, NULL, NULL);
1N/A if (outlen > 0)
1N/A *(outstr+outlen) = _T('\0');
1N/A else
1N/A return NULL;
1N/A }
1N/A free( wcstr );
1N/A return outstr;
1N/A}
1N/A#endif
1N/A
1N/Achar *
1N/Aldaptool_local2UTF8( const char *src )
1N/A{
1N/A char *utf8;
1N/A#ifndef XP_WIN32
1N/A char *locale, *newcharset;
1N/A size_t outLen, resultLen;
1N/A UErrorCode err = U_ZERO_ERROR;
1N/A UConverter *cnv;
1N/A
1N/A if (src == NULL)
1N/A {
1N/A return NULL;
1N/A }
1N/A else if (*src == 0 || (ldaptool_charset == NULL)
1N/A || (!strcmp( ldaptool_charset, "" )))
1N/A {
1N/A /* no option specified, so assume it's already in utf-8 */
1N/A utf8 = strdup(src);
1N/A return utf8;
1N/A }
1N/A
1N/A if( !strcmp( ldaptool_charset, "0" )
1N/A && (!charsetset) )
1N/A {
1N/A /* zero option specified, so try to get default codepage
1N/A this sucker is strdup'd immediately so it's OK to cast */
1N/A newcharset = (char *)ucnv_getDefaultName();
1N/A if (newcharset != NULL) {
1N/A free( ldaptool_charset );
1N/A /* the default codepage lives in ICU */
1N/A ldaptool_charset = strdup(newcharset);
1N/A if (ldaptool_charset == NULL) {
1N/A return strdup(src);
1N/A }
1N/A }
1N/A charsetset = 1;
1N/A }
1N/A else
1N/A if( strcmp( ldaptool_charset, "" ) && (!charsetset) )
1N/A {
1N/A /* -i option specified with charset name */
1N/A charsetset = 1;
1N/A }
1N/A
1N/A /* do the preflight - get the size needed for the target buffer */
1N/A outLen = (size_t) ucnv_convert( "utf-8", ldaptool_charset, NULL, 0, src,
1N/A strlen( src ) * sizeof(char), &err);
1N/A
1N/A if ((err != U_BUFFER_OVERFLOW_ERROR) || (outLen == 0)) {
1N/A /* default to just a copy of the string - this covers
1N/A the case of an illegal charset also */
1N/A return strdup(src);
1N/A }
1N/A
1N/A utf8 = (char *) malloc( outLen + 1);
1N/A if( utf8 == NULL ) {
1N/A /* if we're already out of memory, does strdup just return NULL? */
1N/A return strdup(src);
1N/A }
1N/A
1N/A /* do the actual conversion this time */
1N/A err = U_ZERO_ERROR;
1N/A resultLen = ucnv_convert( "utf-8", ldaptool_charset, utf8, (outLen + 1), src,
1N/A strlen(src) * sizeof(char), &err );
1N/A
1N/A if (!U_SUCCESS(err)) {
1N/A free(utf8);
1N/A return strdup(src);
1N/A }
1N/A
1N/A#else
1N/A utf8 = _convertor(src, FALSE);
1N/A if( utf8 == NULL )
1N/A utf8 = strdup(src);
1N/A#endif
1N/A
1N/A return utf8;
1N/A}
1N/A#endif /* HAVE_LIBICU */
1N/A
1N/A#ifndef HAVE_LIBICU
1N/A#ifdef __cplusplus
1N/A}
1N/A#endif
1N/A#endif