xref: /onnv-gate/usr/src/cmd/ldap/common/convutf8.c (revision 8097:4d57974af082)
10Sstevel@tonic-gate /*
2*8097SSreedhar.Chalamalasetti@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate  * Use is subject to license terms.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate 
60Sstevel@tonic-gate /*
70Sstevel@tonic-gate  * The contents of this file are subject to the Netscape Public
80Sstevel@tonic-gate  * License Version 1.1 (the "License"); you may not use this file
90Sstevel@tonic-gate  * except in compliance with the License. You may obtain a copy of
100Sstevel@tonic-gate  * the License at http://www.mozilla.org/NPL/
110Sstevel@tonic-gate  *
120Sstevel@tonic-gate  * Software distributed under the License is distributed on an "AS
130Sstevel@tonic-gate  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
140Sstevel@tonic-gate  * implied. See the License for the specific language governing
150Sstevel@tonic-gate  * rights and limitations under the License.
160Sstevel@tonic-gate  *
170Sstevel@tonic-gate  * The Original Code is Mozilla Communicator client code, released
180Sstevel@tonic-gate  * March 31, 1998.
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * The Initial Developer of the Original Code is Netscape
210Sstevel@tonic-gate  * Communications Corporation. Portions created by Netscape are
220Sstevel@tonic-gate  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
230Sstevel@tonic-gate  * Rights Reserved.
240Sstevel@tonic-gate  *
250Sstevel@tonic-gate  * Contributor(s):
260Sstevel@tonic-gate  */
270Sstevel@tonic-gate 
280Sstevel@tonic-gate #include <stdio.h>
290Sstevel@tonic-gate #include <stdlib.h>
300Sstevel@tonic-gate #include <string.h>
310Sstevel@tonic-gate #include <locale.h>
320Sstevel@tonic-gate #include <ctype.h>
330Sstevel@tonic-gate 
340Sstevel@tonic-gate #ifndef HAVE_LIBICU
350Sstevel@tonic-gate 
360Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
370Sstevel@tonic-gate #include <errno.h>
380Sstevel@tonic-gate #include <langinfo.h>
390Sstevel@tonic-gate #include <iconv.h>
400Sstevel@tonic-gate #endif
410Sstevel@tonic-gate 
420Sstevel@tonic-gate #ifdef __cplusplus
430Sstevel@tonic-gate extern "C" {
440Sstevel@tonic-gate #endif
450Sstevel@tonic-gate 
460Sstevel@tonic-gate extern char	*ldaptool_charset;
470Sstevel@tonic-gate char		*ldaptool_convdir = NULL;
480Sstevel@tonic-gate static		int charsetset = 0;
490Sstevel@tonic-gate char		*ldaptool_local2UTF8( const char *src );
500Sstevel@tonic-gate 
510Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
520Sstevel@tonic-gate static char 	*ldaptool_convert( const char *src, const char *fcode,
530Sstevel@tonic-gate 				const char *tcode);
540Sstevel@tonic-gate char		*ldaptool_UTF82local( const char *src );
550Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
560Sstevel@tonic-gate 
570Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
580Sstevel@tonic-gate /*
590Sstevel@tonic-gate  * ICU version always returns string, unless strdup fails.
600Sstevel@tonic-gate  * As in ICU version, in case of error strdup(src)
610Sstevel@tonic-gate  * Usually strdup(src) will be ASCII and legal anyways.
620Sstevel@tonic-gate  */
630Sstevel@tonic-gate 
640Sstevel@tonic-gate static char *
ldaptool_convert(const char * src,const char * fcode,const char * tcode)650Sstevel@tonic-gate ldaptool_convert( const char *src, const char *fcode,
660Sstevel@tonic-gate 				 const char *tcode) {
670Sstevel@tonic-gate     char	*dest, *tptr, *tmp;
680Sstevel@tonic-gate     const char	*fptr;
690Sstevel@tonic-gate     iconv_t	cd;
700Sstevel@tonic-gate     size_t	ileft, oleft, ret, size;
710Sstevel@tonic-gate 
720Sstevel@tonic-gate     if (src == NULL)
730Sstevel@tonic-gate 	return (NULL);
740Sstevel@tonic-gate 
750Sstevel@tonic-gate     if (fcode == NULL || tcode == NULL)
760Sstevel@tonic-gate 	return (strdup(src));
770Sstevel@tonic-gate 
780Sstevel@tonic-gate     if (strcasecmp(fcode, tcode) == 0)
790Sstevel@tonic-gate 	return (strdup(src));
800Sstevel@tonic-gate 
810Sstevel@tonic-gate     if ((cd = iconv_open(tcode, fcode)) == (iconv_t)-1) {
820Sstevel@tonic-gate 	/* conversion table not available */
830Sstevel@tonic-gate 	return (strdup(src));
840Sstevel@tonic-gate     }
850Sstevel@tonic-gate 
860Sstevel@tonic-gate     ileft = strlen(src);
870Sstevel@tonic-gate     oleft = 2 * ileft;
880Sstevel@tonic-gate     size = oleft;
890Sstevel@tonic-gate     ret = -1;
900Sstevel@tonic-gate     if ((dest = (char *)malloc(size)) == NULL) {
910Sstevel@tonic-gate 	(void) iconv_close(cd);
920Sstevel@tonic-gate 	/* maybe sizeof strlen(src) memory still exists */
930Sstevel@tonic-gate 	return (strdup(src));
940Sstevel@tonic-gate     }
950Sstevel@tonic-gate     tptr = dest;
960Sstevel@tonic-gate     fptr = src;
970Sstevel@tonic-gate 
980Sstevel@tonic-gate     for (;;) {
990Sstevel@tonic-gate 	ret = iconv(cd, &fptr, &ileft, &tptr, &oleft);
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate 	if (ret != (size_t)-1) {
1020Sstevel@tonic-gate 		/*
1030Sstevel@tonic-gate 		 * Success. Place 'cd' into its initial shift
1040Sstevel@tonic-gate 		 * state before returning.
1050Sstevel@tonic-gate 		 */
1060Sstevel@tonic-gate 		if (fptr == NULL) /* already in initial state  */
1070Sstevel@tonic-gate 			break;
1080Sstevel@tonic-gate 		fptr = NULL;
1090Sstevel@tonic-gate 		ileft = 0;
1100Sstevel@tonic-gate 		continue;
1110Sstevel@tonic-gate 	} if (errno == E2BIG) {
1120Sstevel@tonic-gate 		/*
1130Sstevel@tonic-gate 		 * Lack of space in output buffer.
1140Sstevel@tonic-gate 		 * Hence double the size and retry.
1150Sstevel@tonic-gate 		 * But before calling  iconv(), oleft
1160Sstevel@tonic-gate 		 * and tptr have to re-adjusted, so that
1170Sstevel@tonic-gate 		 * iconv() doesn't overwrite the data
1180Sstevel@tonic-gate 		 * which has already been converted.
1190Sstevel@tonic-gate 		 */
1200Sstevel@tonic-gate 		oleft += size;
1210Sstevel@tonic-gate 		size *= 2;
1220Sstevel@tonic-gate 		if ((tmp = (char *) realloc(dest, size)) == NULL)
1230Sstevel@tonic-gate 			break;
1240Sstevel@tonic-gate 		tptr = tmp + (tptr - dest);
1250Sstevel@tonic-gate 		dest = tmp;
1260Sstevel@tonic-gate 		continue;
1270Sstevel@tonic-gate 	} else {
1280Sstevel@tonic-gate 		/* Other errors */
1290Sstevel@tonic-gate 		break;
1300Sstevel@tonic-gate 	}
1310Sstevel@tonic-gate     }
1320Sstevel@tonic-gate 
1330Sstevel@tonic-gate     if (dest != NULL) {
1340Sstevel@tonic-gate 	if (ret == -1) {
1350Sstevel@tonic-gate     		/* Free malloc'ed memory on failure */
1360Sstevel@tonic-gate 		free(dest);
1370Sstevel@tonic-gate 		dest = NULL;
1380Sstevel@tonic-gate 	} else if (oleft > 0) {
1390Sstevel@tonic-gate 		/* NULL terminate the return value */
1400Sstevel@tonic-gate 		*(dest + (size - oleft)) = '\0';
1410Sstevel@tonic-gate 	} else {
1420Sstevel@tonic-gate 		/* realloc one more byte and NULL terminate */
1430Sstevel@tonic-gate 		if ((tmp = (char *) realloc(dest, size + 1)) == NULL) {
1440Sstevel@tonic-gate 			free(dest);
1450Sstevel@tonic-gate 			dest = NULL;
1460Sstevel@tonic-gate 		} else {
1470Sstevel@tonic-gate 			*(dest + size) = '\0';
1480Sstevel@tonic-gate 		}
1490Sstevel@tonic-gate 	}
1500Sstevel@tonic-gate     }
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate     (void) iconv_close(cd);
1530Sstevel@tonic-gate     if (dest == NULL) {
1540Sstevel@tonic-gate 	/* last chance in case some other failure along the way occurs */
1550Sstevel@tonic-gate 	return (strdup(src));
1560Sstevel@tonic-gate     }
1570Sstevel@tonic-gate     return (dest);
1580Sstevel@tonic-gate }
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate char *
ldaptool_UTF82local(const char * src)1610Sstevel@tonic-gate ldaptool_UTF82local( const char *src )
1620Sstevel@tonic-gate {
1630Sstevel@tonic-gate     char *to_code;
1640Sstevel@tonic-gate     if ((to_code = nl_langinfo(CODESET)) == NULL)
1650Sstevel@tonic-gate 	return (strdup(src));
1660Sstevel@tonic-gate     return (ldaptool_convert(src, "UTF-8", (const char *)to_code));
1670Sstevel@tonic-gate }
1680Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate char *
ldaptool_local2UTF8(const char * src)1710Sstevel@tonic-gate ldaptool_local2UTF8( const char *src )
1720Sstevel@tonic-gate {
1730Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
1740Sstevel@tonic-gate     char *from_code;
1750Sstevel@tonic-gate     if ((from_code = nl_langinfo(CODESET)) == NULL)
1760Sstevel@tonic-gate 	return (strdup(src));
1770Sstevel@tonic-gate     return (ldaptool_convert(src, (const char *)from_code, "UTF-8"));
1780Sstevel@tonic-gate #else
1790Sstevel@tonic-gate     char *utf8;
1800Sstevel@tonic-gate     charsetset = 0;
1810Sstevel@tonic-gate     if (src == NULL)
1820Sstevel@tonic-gate     {
1830Sstevel@tonic-gate 	return NULL;
1840Sstevel@tonic-gate     }
1850Sstevel@tonic-gate     utf8 = strdup(src);
1860Sstevel@tonic-gate     return ( utf8 );
1870Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
1880Sstevel@tonic-gate }
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate #else /* HAVE_LIBICU */
1910Sstevel@tonic-gate 
1920Sstevel@tonic-gate #include "unicode/utypes.h"
1930Sstevel@tonic-gate #include "unicode/ucnv.h"
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate #define NSPR20
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate #ifdef XP_WIN32
1980Sstevel@tonic-gate #define  VC_EXTRALEAN
1990Sstevel@tonic-gate #include <afxwin.h>
2000Sstevel@tonic-gate #include <winnls.h>
2010Sstevel@tonic-gate #endif
2020Sstevel@tonic-gate 
2030Sstevel@tonic-gate extern char *ldaptool_charset;
2040Sstevel@tonic-gate static int charsetset = 0;
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate extern "C" {
2070Sstevel@tonic-gate char *ldaptool_convdir = NULL;
2080Sstevel@tonic-gate char *ldaptool_local2UTF8( const char * );
2090Sstevel@tonic-gate }
2100Sstevel@tonic-gate 
2110Sstevel@tonic-gate #ifndef XP_WIN32
2120Sstevel@tonic-gate char * GetNormalizedLocaleName(void);
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate char *
2160Sstevel@tonic-gate GetNormalizedLocaleName(void)
2170Sstevel@tonic-gate {
2180Sstevel@tonic-gate #ifdef _HPUX_SOURCE
2190Sstevel@tonic-gate 
2200Sstevel@tonic-gate     int    len;
2210Sstevel@tonic-gate     char    *locale;
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate     locale = setlocale(LC_CTYPE, "");
2240Sstevel@tonic-gate     if (locale && *locale) {
2250Sstevel@tonic-gate         len = strlen(locale);
2260Sstevel@tonic-gate     } else {
2270Sstevel@tonic-gate         locale = "C";
2280Sstevel@tonic-gate         len = 1;
2290Sstevel@tonic-gate     }
2300Sstevel@tonic-gate 
2310Sstevel@tonic-gate     if ((!strncmp(locale, "/\x03:", 3)) &&
2320Sstevel@tonic-gate         (!strcmp(&locale[len - 2], ";/"))) {
2330Sstevel@tonic-gate         locale += 3;
2340Sstevel@tonic-gate         len -= 5;
2350Sstevel@tonic-gate     }
2360Sstevel@tonic-gate 
2370Sstevel@tonic-gate     locale = strdup(locale);
2380Sstevel@tonic-gate     if (locale) {
2390Sstevel@tonic-gate         locale[len] = 0;
2400Sstevel@tonic-gate     }
2410Sstevel@tonic-gate 
2420Sstevel@tonic-gate     return locale;
2430Sstevel@tonic-gate 
2440Sstevel@tonic-gate #else
2450Sstevel@tonic-gate 
2460Sstevel@tonic-gate     char    *locale;
2470Sstevel@tonic-gate 
2480Sstevel@tonic-gate     locale = setlocale(LC_CTYPE, "");
2490Sstevel@tonic-gate     if (locale && *locale) {
2500Sstevel@tonic-gate         return strdup(locale);
2510Sstevel@tonic-gate     }
2520Sstevel@tonic-gate 
2530Sstevel@tonic-gate     return strdup("C");
2540Sstevel@tonic-gate 
2550Sstevel@tonic-gate #endif
2560Sstevel@tonic-gate }
2570Sstevel@tonic-gate 
2580Sstevel@tonic-gate #if defined(IRIX)
2590Sstevel@tonic-gate const char *CHARCONVTABLE[] =
2600Sstevel@tonic-gate {
2610Sstevel@tonic-gate "! This table maps the host's locale names to IANA charsets",
2620Sstevel@tonic-gate "!",
2630Sstevel@tonic-gate "C:             ISO_8859-1:1987",
2640Sstevel@tonic-gate "cs:            ISO_8859-2:1987",
2650Sstevel@tonic-gate "da:            ISO_8859-1:1987",
2660Sstevel@tonic-gate "de:            ISO_8859-1:1987",
2670Sstevel@tonic-gate "de_AT:         ISO_8859-1:1987",
2680Sstevel@tonic-gate "de_CH:         ISO_8859-1:1987",
2690Sstevel@tonic-gate "en:            ISO_8859-1:1987",
2700Sstevel@tonic-gate "en_AU:         ISO_8859-1:1987",
2710Sstevel@tonic-gate "en_CA:         ISO_8859-1:1987",
2720Sstevel@tonic-gate "en_TH:         ISO_8859-1:1987",
2730Sstevel@tonic-gate "en_US:         ISO_8859-1:1987",
2740Sstevel@tonic-gate "es:            ISO_8859-1:1987",
2750Sstevel@tonic-gate "fi:            ISO_8859-1:1987",
2760Sstevel@tonic-gate "fr:            ISO_8859-1:1987",
2770Sstevel@tonic-gate "fr_BE:         ISO_8859-1:1987",
2780Sstevel@tonic-gate "fr_CA:         ISO_8859-1:1987",
2790Sstevel@tonic-gate "fr_CH:         ISO_8859-1:1987",
2800Sstevel@tonic-gate "is:            ISO_8859-1:1987",
2810Sstevel@tonic-gate "it:            ISO_8859-1:1987",
2820Sstevel@tonic-gate "it_CH:         ISO_8859-1:1987",
2830Sstevel@tonic-gate "ja_JP.EUC:     Extended_UNIX_Code_Packed_Format_for_Japanese",
2840Sstevel@tonic-gate "ko_KR.euc:     EUC-KR",
2850Sstevel@tonic-gate "nl:            ISO_8859-1:1987",
2860Sstevel@tonic-gate "nl_BE:         ISO_8859-1:1987",
2870Sstevel@tonic-gate "no:            ISO_8859-1:1987",
2880Sstevel@tonic-gate "pl:            ISO_8859-2:1987",
2890Sstevel@tonic-gate "pt:            ISO_8859-1:1987",
2900Sstevel@tonic-gate "sh:            ISO_8859-2:1987",
2910Sstevel@tonic-gate "sk:            ISO_8859-2:1987",
2920Sstevel@tonic-gate "sv:            ISO_8859-1:1987",
2930Sstevel@tonic-gate "zh_CN.ugb:     GB2312",
2940Sstevel@tonic-gate "zh_TW.ucns:    cns11643_1",
2950Sstevel@tonic-gate NULL
2960Sstevel@tonic-gate };
2970Sstevel@tonic-gate #elif defined(SOLARIS)
2980Sstevel@tonic-gate const char *CHARCONVTABLE[] =
2990Sstevel@tonic-gate {
3000Sstevel@tonic-gate "! This table maps the host's locale names to IANA charsets",
3010Sstevel@tonic-gate "!",
3020Sstevel@tonic-gate "C:             ISO_8859-1:1987",
3030Sstevel@tonic-gate "ja:            Extended_UNIX_Code_Packed_Format_for_Japanese",
3040Sstevel@tonic-gate "ja_JP.EUC:     Extended_UNIX_Code_Packed_Format_for_Japanese",
3050Sstevel@tonic-gate "ja_JP.PCK:     Shift_JIS",
3060Sstevel@tonic-gate "en:		ISO_8859-1:1987",
3070Sstevel@tonic-gate "en_AU:		ISO_8859-1:1987",
3080Sstevel@tonic-gate "en_CA:		ISO_8859-1:1987",
3090Sstevel@tonic-gate "en_UK:		ISO_8859-1:1987",
3100Sstevel@tonic-gate "en_US:		ISO_8859-1:1987",
3110Sstevel@tonic-gate "es:		ISO_8859-1:1987",
3120Sstevel@tonic-gate "es_AR:		ISO_8859-1:1987",
3130Sstevel@tonic-gate "es_BO:		ISO_8859-1:1987",
3140Sstevel@tonic-gate "es_CL:		ISO_8859-1:1987",
3150Sstevel@tonic-gate "es_CO:		ISO_8859-1:1987",
3160Sstevel@tonic-gate "es_CR:		ISO_8859-1:1987",
3170Sstevel@tonic-gate "es_EC:		ISO_8859-1:1987",
3180Sstevel@tonic-gate "es_GT:		ISO_8859-1:1987",
3190Sstevel@tonic-gate "es_MX:		ISO_8859-1:1987",
3200Sstevel@tonic-gate "es_NI:		ISO_8859-1:1987",
3210Sstevel@tonic-gate "es_PA:		ISO_8859-1:1987",
3220Sstevel@tonic-gate "es_PE:		ISO_8859-1:1987",
3230Sstevel@tonic-gate "es_PY:		ISO_8859-1:1987",
3240Sstevel@tonic-gate "es_SV:		ISO_8859-1:1987",
3250Sstevel@tonic-gate "es_UY:		ISO_8859-1:1987",
3260Sstevel@tonic-gate "es_VE:		ISO_8859-1:1987",
3270Sstevel@tonic-gate "fr:		ISO_8859-1:1987",
3280Sstevel@tonic-gate "fr_BE:		ISO_8859-1:1987",
3290Sstevel@tonic-gate "fr_CA:		ISO_8859-1:1987",
3300Sstevel@tonic-gate "fr_CH:		ISO_8859-1:1987",
3310Sstevel@tonic-gate "de:		ISO_8859-1:1987",
3320Sstevel@tonic-gate "de_AT:		ISO_8859-1:1987",
3330Sstevel@tonic-gate "de_CH:		ISO_8859-1:1987",
3340Sstevel@tonic-gate "nl:		ISO_8859-1:1987",
3350Sstevel@tonic-gate "nl_BE:		ISO_8859-1:1987",
3360Sstevel@tonic-gate "it:		ISO_8859-1:1987",
3370Sstevel@tonic-gate "sv:		ISO_8859-1:1987",
3380Sstevel@tonic-gate "no:		ISO_8859-1:1987",
3390Sstevel@tonic-gate "da:		ISO_8859-1:1987",
3400Sstevel@tonic-gate "iso_8859_1:    ISO_8859-1:1987",
3410Sstevel@tonic-gate "japanese:      Extended_UNIX_Code_Packed_Format_for_Japanese",
3420Sstevel@tonic-gate "ko:            EUC-KR",
3430Sstevel@tonic-gate "zh:            GB2312",
3440Sstevel@tonic-gate "zh_TW:         cns11643_1",
3450Sstevel@tonic-gate NULL
3460Sstevel@tonic-gate };
3470Sstevel@tonic-gate #elif defined(OSF1)
3480Sstevel@tonic-gate const char *CHARCONVTABLE[] =
3490Sstevel@tonic-gate {
3500Sstevel@tonic-gate "! This table maps the host's locale names to IANA charsets",
3510Sstevel@tonic-gate "!",
3520Sstevel@tonic-gate "C:                     ISO_8859-1:1987",
3530Sstevel@tonic-gate "cs_CZ.ISO8859-2:       ISO_8859-2:1987",
3540Sstevel@tonic-gate "cs_CZ:                 ISO_8859-2:1987",
3550Sstevel@tonic-gate "da_DK.ISO8859-1:       ISO_8859-1:1987",
3560Sstevel@tonic-gate "de_CH.ISO8859-1:       ISO_8859-1:1987",
3570Sstevel@tonic-gate "de_DE.ISO8859-1:       ISO_8859-1:1987",
3580Sstevel@tonic-gate "en_GB.ISO8859-1:       ISO_8859-1:1987",
3590Sstevel@tonic-gate "en_US.ISO8859-1:       ISO_8859-1:1987",
3600Sstevel@tonic-gate "es_ES.ISO8859-1:       ISO_8859-1:1987",
3610Sstevel@tonic-gate "fi_FI.ISO8859-1:       ISO_8859-1:1987",
3620Sstevel@tonic-gate "fr_BE.ISO8859-1:       ISO_8859-1:1987",
3630Sstevel@tonic-gate "fr_CA.ISO8859-1:       ISO_8859-1:1987",
3640Sstevel@tonic-gate "fr_CH.ISO8859-1:       ISO_8859-1:1987",
3650Sstevel@tonic-gate "fr_FR.ISO8859-1:       ISO_8859-1:1987",
3660Sstevel@tonic-gate "hu_HU.ISO8859-2:       ISO_8859-2:1987",
3670Sstevel@tonic-gate "hu_HU:                 ISO_8859-2:1987",
3680Sstevel@tonic-gate "is_IS.ISO8859-1:       ISO_8859-1:1987",
3690Sstevel@tonic-gate "it_IT.ISO8859-1:       ISO_8859-1:1987",
3700Sstevel@tonic-gate "ja_JP.SJIS:            Shift_JIS",
3710Sstevel@tonic-gate "ja_JP.eucJP:           Extended_UNIX_Code_Packed_Format_for_Japanese",
3720Sstevel@tonic-gate "ja_JP:                 Extended_UNIX_Code_Packed_Format_for_Japanese",
3730Sstevel@tonic-gate "ko_KR.eucKR:           EUC-KR",
3740Sstevel@tonic-gate "ko_KR:                 EUC-KR",
3750Sstevel@tonic-gate "nl_BE.ISO8859-1:       ISO_8859-1:1987",
3760Sstevel@tonic-gate "nl_NL.ISO8859-1:       ISO_8859-1:1987",
3770Sstevel@tonic-gate "no_NO.ISO8859-1:       ISO_8859-1:1987",
3780Sstevel@tonic-gate "pl_PL.ISO8859-2:       ISO_8859-2:1987",
3790Sstevel@tonic-gate "pl_PL:                 ISO_8859-2:1987",
3800Sstevel@tonic-gate "pt_PT.ISO8859-1:       ISO_8859-1:1987",
3810Sstevel@tonic-gate "sk_SK.ISO8859-2:       ISO_8859-2:1987",
3820Sstevel@tonic-gate "sk_SK:                 ISO_8859-2:1987",
3830Sstevel@tonic-gate "sv_SE.ISO8859-1:       ISO_8859-1:1987",
3840Sstevel@tonic-gate "zh_CN:                 GB2312",
3850Sstevel@tonic-gate "zh_HK.big5:            Big5",
3860Sstevel@tonic-gate "zh_HK.eucTW:           cns11643_1",
3870Sstevel@tonic-gate "zh_TW.big5:            Big5",
3880Sstevel@tonic-gate "zh_TW.big5@chuyin:     Big5",
3890Sstevel@tonic-gate "zh_TW.big5@radical:    Big5",
3900Sstevel@tonic-gate "zh_TW.big5@stroke:     Big5",
3910Sstevel@tonic-gate "zh_TW.eucTW:           cns11643_1",
3920Sstevel@tonic-gate "zh_TW.eucTW@chuyin:    cns11643_1",
3930Sstevel@tonic-gate "zh_TW.eucTW@radical:   cns11643_1",
3940Sstevel@tonic-gate "zh_TW.eucTW@stroke:    cns11643_1",
3950Sstevel@tonic-gate "zh_TW:                 cns11643_1",
3960Sstevel@tonic-gate NULL
3970Sstevel@tonic-gate };
3980Sstevel@tonic-gate #elif defined(HPUX)
3990Sstevel@tonic-gate const char *CHARCONVTABLE[] =
4000Sstevel@tonic-gate {
4010Sstevel@tonic-gate "! This table maps the host's locale names to IANA charsets",
4020Sstevel@tonic-gate "!",
4030Sstevel@tonic-gate "C:			ISO_8859-1:1987",
4040Sstevel@tonic-gate "ja_JP:			Extended_UNIX_Code_Packed_Format_for_Japanese",
4050Sstevel@tonic-gate "ja_JP.SJIS:		Shift_JIS",
4060Sstevel@tonic-gate "ja_JP.eucJP:		Extended_UNIX_Code_Packed_Format_for_Japanese",
4070Sstevel@tonic-gate "es_ES:			ISO_8859-1:1987",
4080Sstevel@tonic-gate "es_ES.iso88591:	ISO_8859-1:1987",
4090Sstevel@tonic-gate "sv_SE:			ISO_8859-1:1987",
4100Sstevel@tonic-gate "sv_SE.iso88591:	ISO_8859-1:1987",
4110Sstevel@tonic-gate "da_DK:			ISO_8859-1:1987",
4120Sstevel@tonic-gate "da_DK.iso88591:	ISO_8859-1:1987",
4130Sstevel@tonic-gate "nl_NL:			ISO_8859-1:1987",
4140Sstevel@tonic-gate "nl_NL.iso88591:	ISO_8859-1:1987",
4150Sstevel@tonic-gate "en:			ISO_8859-1:1987",
4160Sstevel@tonic-gate "en_GB:			ISO_8859-1:1987",
4170Sstevel@tonic-gate "en_GB.iso88591:	ISO_8859-1:1987",
4180Sstevel@tonic-gate "en_US:			ISO_8859-1:1987",
4190Sstevel@tonic-gate "en_US.iso88591:	ISO_8859-1:1987",
4200Sstevel@tonic-gate "fi_FI:			ISO_8859-1:1987",
4210Sstevel@tonic-gate "fi_FI.iso88591:	ISO_8859-1:1987",
4220Sstevel@tonic-gate "fr_CA:			ISO_8859-1:1987",
4230Sstevel@tonic-gate "fr_CA.iso88591:	ISO_8859-1:1987",
4240Sstevel@tonic-gate "fr_FR:			ISO_8859-1:1987",
4250Sstevel@tonic-gate "fr_FR.iso88591:	ISO_8859-1:1987",
4260Sstevel@tonic-gate "de_DE:			ISO_8859-1:1987",
4270Sstevel@tonic-gate "de_DE.iso88591:	ISO_8859-1:1987",
4280Sstevel@tonic-gate "is_IS:			ISO_8859-1:1987",
4290Sstevel@tonic-gate "is_IS.iso88591:	ISO_8859-1:1987",
4300Sstevel@tonic-gate "it_IT:			ISO_8859-1:1987",
4310Sstevel@tonic-gate "it_IT.iso88591:	ISO_8859-1:1987",
4320Sstevel@tonic-gate "no_NO:			ISO_8859-1:1987",
4330Sstevel@tonic-gate "no_NO.iso88591:	ISO_8859-1:1987",
4340Sstevel@tonic-gate "pt_PT:			ISO_8859-1:1987",
4350Sstevel@tonic-gate "pt_PT.iso88591:	ISO_8859-1:1987",
4360Sstevel@tonic-gate "hu_HU:			ISO_8859-2:1987",
4370Sstevel@tonic-gate "hu_HU.iso88592:	ISO_8859-2:1987",
4380Sstevel@tonic-gate "cs_CZ:			ISO_8859-2:1987",
4390Sstevel@tonic-gate "cs_CZ.iso88592:	ISO_8859-2:1987",
4400Sstevel@tonic-gate "pl_PL:			ISO_8859-2:1987",
4410Sstevel@tonic-gate "pl_PL.iso88592:	ISO_8859-2:1987",
4420Sstevel@tonic-gate "ro_RO:			ISO_8859-2:1987",
4430Sstevel@tonic-gate "ro_RO.iso88592:	ISO_8859-2:1987",
4440Sstevel@tonic-gate "hr_HR:			ISO_8859-2:1987",
4450Sstevel@tonic-gate "hr_HR.iso88592:	ISO_8859-2:1987",
4460Sstevel@tonic-gate "sk_SK:			ISO_8859-2:1987",
4470Sstevel@tonic-gate "sk_SK.iso88592:	ISO_8859-2:1987",
4480Sstevel@tonic-gate "sl_SI:			ISO_8859-2:1987",
4490Sstevel@tonic-gate "sl_SI.iso88592:	ISO_8859-2:1987",
4500Sstevel@tonic-gate "american.iso88591:     ISO_8859-1:1987",
4510Sstevel@tonic-gate "bulgarian:             ISO_8859-2:1987",
4520Sstevel@tonic-gate "c-french.iso88591:     ISO_8859-1:1987",
4530Sstevel@tonic-gate "chinese-s:             GB2312",
4540Sstevel@tonic-gate "chinese-t.big5:                Big5",
4550Sstevel@tonic-gate "czech:                 ISO_8859-2:1987",
4560Sstevel@tonic-gate "danish.iso88591:       ISO_8859-1:1987",
4570Sstevel@tonic-gate "dutch.iso88591:                ISO_8859-1:1987",
4580Sstevel@tonic-gate "english.iso88591:      ISO_8859-1:1987",
4590Sstevel@tonic-gate "finnish.iso88591:      ISO_8859-1:1987",
4600Sstevel@tonic-gate "french.iso88591:       ISO_8859-1:1987",
4610Sstevel@tonic-gate "german.iso88591:       ISO_8859-1:1987",
4620Sstevel@tonic-gate "hungarian:             ISO_8859-2:1987",
4630Sstevel@tonic-gate "icelandic.iso88591:    ISO_8859-1:1987",
4640Sstevel@tonic-gate "italian.iso88591:      ISO_8859-1:1987",
4650Sstevel@tonic-gate "japanese.euc:          Extended_UNIX_Code_Packed_Format_for_Japanese",
4660Sstevel@tonic-gate "japanese:              Shift_JIS",
4670Sstevel@tonic-gate "katakana:              Shift_JIS",
4680Sstevel@tonic-gate "korean:                        EUC-KR",
4690Sstevel@tonic-gate "norwegian.iso88591:    ISO_8859-1:1987",
4700Sstevel@tonic-gate "polish:                        ISO_8859-2:1987",
4710Sstevel@tonic-gate "portuguese.iso88591:   ISO_8859-1:1987",
4720Sstevel@tonic-gate "rumanian:              ISO_8859-2:1987",
4730Sstevel@tonic-gate "serbocroatian:         ISO_8859-2:1987",
4740Sstevel@tonic-gate "slovene:               ISO_8859-2:1987",
4750Sstevel@tonic-gate "spanish.iso88591:      ISO_8859-1:1987",
4760Sstevel@tonic-gate "swedish.iso88591:      ISO_8859-1:1987",
4770Sstevel@tonic-gate NULL
4780Sstevel@tonic-gate };
4790Sstevel@tonic-gate #elif defined(AIX)
4800Sstevel@tonic-gate const char *CHARCONVTABLE[] =
4810Sstevel@tonic-gate {
4820Sstevel@tonic-gate "! This table maps the host's locale names to IANA charsets",
4830Sstevel@tonic-gate "!",
4840Sstevel@tonic-gate "C:                     ISO_8859-1:1987",
4850Sstevel@tonic-gate "En_JP.IBM-932:         Shift_JIS",
4860Sstevel@tonic-gate "En_JP:                 Shift_JIS",
4870Sstevel@tonic-gate "Ja_JP.IBM-932:         Shift_JIS",
4880Sstevel@tonic-gate "Ja_JP:                 Shift_JIS",
4890Sstevel@tonic-gate "da_DK.ISO8859-1:       ISO_8859-1:1987",
4900Sstevel@tonic-gate "da_DK:                 ISO_8859-1:1987",
4910Sstevel@tonic-gate "de_CH.ISO8859-1:       ISO_8859-1:1987",
4920Sstevel@tonic-gate "de_CH:                 ISO_8859-1:1987",
4930Sstevel@tonic-gate "de_DE.ISO8859-1:       ISO_8859-1:1987",
4940Sstevel@tonic-gate "de_DE:                 ISO_8859-1:1987",
4950Sstevel@tonic-gate "en_GB.ISO8859-1:       ISO_8859-1:1987",
4960Sstevel@tonic-gate "en_GB:                 ISO_8859-1:1987",
4970Sstevel@tonic-gate "en_JP.IBM-eucJP:       Extended_UNIX_Code_Packed_Format_for_Japanese",
4980Sstevel@tonic-gate "en_JP:                 Extended_UNIX_Code_Packed_Format_for_Japanese",
4990Sstevel@tonic-gate "en_KR.IBM-eucKR:       EUC-KR",
5000Sstevel@tonic-gate "en_KR:                 EUC-KR",
5010Sstevel@tonic-gate "en_TW.IBM-eucTW:       cns11643_1",
5020Sstevel@tonic-gate "en_TW:                 cns11643_1",
5030Sstevel@tonic-gate "en_US.ISO8859-1:       ISO_8859-1:1987",
5040Sstevel@tonic-gate "en_US:                 ISO_8859-1:1987",
5050Sstevel@tonic-gate "es_ES.ISO8859-1:       ISO_8859-1:1987",
5060Sstevel@tonic-gate "es_ES:                 ISO_8859-1:1987",
5070Sstevel@tonic-gate "fi_FI.ISO8859-1:       ISO_8859-1:1987",
5080Sstevel@tonic-gate "fi_FI:                 ISO_8859-1:1987",
5090Sstevel@tonic-gate "fr_BE.ISO8859-1:       ISO_8859-1:1987",
5100Sstevel@tonic-gate "fr_BE:                 ISO_8859-1:1987",
5110Sstevel@tonic-gate "fr_CA.ISO8859-1:       ISO_8859-1:1987",
5120Sstevel@tonic-gate "fr_CA:                 ISO_8859-1:1987",
5130Sstevel@tonic-gate "fr_CH.ISO8859-1:       ISO_8859-1:1987",
5140Sstevel@tonic-gate "fr_CH:                 ISO_8859-1:1987",
5150Sstevel@tonic-gate "fr_FR.ISO8859-1:       ISO_8859-1:1987",
5160Sstevel@tonic-gate "fr_FR:                 ISO_8859-1:1987",
5170Sstevel@tonic-gate "is_IS.ISO8859-1:       ISO_8859-1:1987",
5180Sstevel@tonic-gate "is_IS:                 ISO_8859-1:1987",
5190Sstevel@tonic-gate "it_IT.ISO8859-1:       ISO_8859-1:1987",
5200Sstevel@tonic-gate "it_IT:                 ISO_8859-1:1987",
5210Sstevel@tonic-gate "ja_JP.IBM-eucJP:       Extended_UNIX_Code_Packed_Format_for_Japanese",
5220Sstevel@tonic-gate "ja_JP:                 Extended_UNIX_Code_Packed_Format_for_Japanese",
5230Sstevel@tonic-gate "ko_KR.IBM-eucKR:       EUC-KR",
5240Sstevel@tonic-gate "ko_KR:                 EUC-KR",
5250Sstevel@tonic-gate "nl_BE.ISO8859-1:       ISO_8859-1:1987",
5260Sstevel@tonic-gate "nl_BE:                 ISO_8859-1:1987",
5270Sstevel@tonic-gate "nl_NL.ISO8859-1:       ISO_8859-1:1987",
5280Sstevel@tonic-gate "nl_NL:                 ISO_8859-1:1987",
5290Sstevel@tonic-gate "no_NO.ISO8859-1:       ISO_8859-1:1987",
5300Sstevel@tonic-gate "no_NO:                 ISO_8859-1:1987",
5310Sstevel@tonic-gate "pt_PT.ISO8859-1:       ISO_8859-1:1987",
5320Sstevel@tonic-gate "pt_PT:                 ISO_8859-1:1987",
5330Sstevel@tonic-gate "sv_SE.ISO8859-1:       ISO_8859-1:1987",
5340Sstevel@tonic-gate "sv_SE:                 ISO_8859-1:1987",
5350Sstevel@tonic-gate "zh_TW.IBM-eucTW:       cns11643_1",
5360Sstevel@tonic-gate "zh_TW:                 cns11643_1",
5370Sstevel@tonic-gate NULL
5380Sstevel@tonic-gate };
5390Sstevel@tonic-gate #else   // sunos by default
5400Sstevel@tonic-gate const char *CHARCONVTABLE[] =
5410Sstevel@tonic-gate {
5420Sstevel@tonic-gate "! This table maps the host's locale names to IANA charsets",
5430Sstevel@tonic-gate "!",
5440Sstevel@tonic-gate "C:             ISO_8859-1:1987",
5450Sstevel@tonic-gate "de:            ISO_8859-1:1987",
5460Sstevel@tonic-gate "en_US:         ISO_8859-1:1987",
5470Sstevel@tonic-gate "es:            ISO_8859-1:1987",
5480Sstevel@tonic-gate "fr:            ISO_8859-1:1987",
5490Sstevel@tonic-gate "iso_8859_1:    ISO_8859-1:1987",
5500Sstevel@tonic-gate "it:            ISO_8859-1:1987",
5510Sstevel@tonic-gate "ja:            Extended_UNIX_Code_Packed_Format_for_Japanese",
5520Sstevel@tonic-gate "ja_JP.EUC:     Extended_UNIX_Code_Packed_Format_for_Japanese",
5530Sstevel@tonic-gate "japanese:      Extended_UNIX_Code_Packed_Format_for_Japanese",
5540Sstevel@tonic-gate "ko:            EUC-KR",
5550Sstevel@tonic-gate "sv:            ISO_8859-1:1987",
5560Sstevel@tonic-gate "zh:            GB2312",
5570Sstevel@tonic-gate "zh_TW:         cns11643_1",
5580Sstevel@tonic-gate NULL
5590Sstevel@tonic-gate };
5600Sstevel@tonic-gate #endif
5610Sstevel@tonic-gate 
5620Sstevel@tonic-gate #define BSZ     256
5630Sstevel@tonic-gate 
5640Sstevel@tonic-gate char *
5650Sstevel@tonic-gate GetCharsetFromLocale(char *locale)
5660Sstevel@tonic-gate {
5670Sstevel@tonic-gate     char *tmpcharset = NULL;
5680Sstevel@tonic-gate     char buf[BSZ];
5690Sstevel@tonic-gate     char *p;
5700Sstevel@tonic-gate     const char *line;
5710Sstevel@tonic-gate     int i=0;
5720Sstevel@tonic-gate 
5730Sstevel@tonic-gate     line = CHARCONVTABLE[i];
5740Sstevel@tonic-gate     while (line != NULL)
5750Sstevel@tonic-gate     {
5760Sstevel@tonic-gate        if (*line == 0)
5770Sstevel@tonic-gate        {
5780Sstevel@tonic-gate           break;
5790Sstevel@tonic-gate        }
5800Sstevel@tonic-gate 
5810Sstevel@tonic-gate        strcpy(buf, line);
5820Sstevel@tonic-gate        line = CHARCONVTABLE[++i];
5830Sstevel@tonic-gate 
5840Sstevel@tonic-gate        if (strlen(buf) == 0 || buf[0] == '!')
5850Sstevel@tonic-gate        {
5860Sstevel@tonic-gate           continue;
5870Sstevel@tonic-gate        }
5880Sstevel@tonic-gate        p = strchr(buf, ':');
5890Sstevel@tonic-gate        if (p == NULL)
5900Sstevel@tonic-gate        {
5910Sstevel@tonic-gate           tmpcharset = NULL;
5920Sstevel@tonic-gate           break;
5930Sstevel@tonic-gate        }
5940Sstevel@tonic-gate        *p = 0;
5950Sstevel@tonic-gate        if (strcmp(buf, locale) == 0) {
5960Sstevel@tonic-gate           while (*++p == ' ' || *p == '\t')
5970Sstevel@tonic-gate              ;
5980Sstevel@tonic-gate           if (isalpha(*p)) {
5990Sstevel@tonic-gate              tmpcharset = strdup(p);
6000Sstevel@tonic-gate           } else
6010Sstevel@tonic-gate              tmpcharset = NULL;
6020Sstevel@tonic-gate 
6030Sstevel@tonic-gate           break;
6040Sstevel@tonic-gate        }
6050Sstevel@tonic-gate     }
6060Sstevel@tonic-gate     return tmpcharset;
6070Sstevel@tonic-gate }
6080Sstevel@tonic-gate 
6090Sstevel@tonic-gate #endif /* Not defined XP_WIN32 */
6100Sstevel@tonic-gate 
6110Sstevel@tonic-gate #ifdef XP_WIN32
6120Sstevel@tonic-gate char *_convertor(const char *instr, int bFromUTF8)
6130Sstevel@tonic-gate {
6140Sstevel@tonic-gate     char  *outstr = NULL;
6150Sstevel@tonic-gate     int    inlen, wclen, outlen;
6160Sstevel@tonic-gate     LPWSTR wcstr;
6170Sstevel@tonic-gate 
6180Sstevel@tonic-gate     if (instr == NULL)
6190Sstevel@tonic-gate             return NULL;
6200Sstevel@tonic-gate 
6210Sstevel@tonic-gate     if ((inlen = strlen(instr)) <= 0)
6220Sstevel@tonic-gate             return NULL;
6230Sstevel@tonic-gate 
6240Sstevel@tonic-gate     /* output never becomes longer than input,
6250Sstevel@tonic-gate      * thus we don't have to ask for the length
6260Sstevel@tonic-gate      */
6270Sstevel@tonic-gate     wcstr = (LPWSTR) malloc( sizeof( WCHAR ) * (inlen+1) );
6280Sstevel@tonic-gate     if (!wcstr)
6290Sstevel@tonic-gate         return NULL;
6300Sstevel@tonic-gate 
6310Sstevel@tonic-gate     wclen = MultiByteToWideChar(bFromUTF8 ? CP_UTF8 : CP_ACP, 0, instr,
6320Sstevel@tonic-gate                                  inlen, wcstr, inlen);
6330Sstevel@tonic-gate     outlen = WideCharToMultiByte(bFromUTF8 ? CP_ACP : CP_UTF8, 0, wcstr,
6340Sstevel@tonic-gate                                   wclen, NULL, 0, NULL, NULL);
6350Sstevel@tonic-gate 
6360Sstevel@tonic-gate     if (outlen > 0) {
6370Sstevel@tonic-gate         outstr = (char *) malloc(outlen + 2);
6380Sstevel@tonic-gate         outlen = WideCharToMultiByte(bFromUTF8 ? CP_ACP : CP_UTF8, 0, wcstr,
6390Sstevel@tonic-gate                                       wclen, outstr, outlen, NULL, NULL);
6400Sstevel@tonic-gate         if (outlen > 0)
6410Sstevel@tonic-gate             *(outstr+outlen) = _T('\0');
6420Sstevel@tonic-gate         else
6430Sstevel@tonic-gate             return NULL;
6440Sstevel@tonic-gate     }
6450Sstevel@tonic-gate     free( wcstr );
6460Sstevel@tonic-gate     return outstr;
6470Sstevel@tonic-gate }
6480Sstevel@tonic-gate #endif
6490Sstevel@tonic-gate 
6500Sstevel@tonic-gate char *
6510Sstevel@tonic-gate ldaptool_local2UTF8( const char *src )
6520Sstevel@tonic-gate {
6530Sstevel@tonic-gate     char *utf8;
6540Sstevel@tonic-gate #ifndef XP_WIN32
6550Sstevel@tonic-gate     char *locale, *newcharset;
6560Sstevel@tonic-gate     size_t outLen, resultLen;
6570Sstevel@tonic-gate     UErrorCode err = U_ZERO_ERROR;
6580Sstevel@tonic-gate     UConverter *cnv;
6590Sstevel@tonic-gate 
6600Sstevel@tonic-gate     if (src == NULL)
6610Sstevel@tonic-gate     {
6620Sstevel@tonic-gate       return NULL;
6630Sstevel@tonic-gate     }
6640Sstevel@tonic-gate     else if (*src == 0 || (ldaptool_charset == NULL)
6650Sstevel@tonic-gate 	     || (!strcmp( ldaptool_charset, "" )))
6660Sstevel@tonic-gate     {
6670Sstevel@tonic-gate 	/* no option specified, so assume it's already in utf-8 */
6680Sstevel@tonic-gate         utf8 = strdup(src);
6690Sstevel@tonic-gate         return utf8;
6700Sstevel@tonic-gate     }
6710Sstevel@tonic-gate 
6720Sstevel@tonic-gate     if( !strcmp( ldaptool_charset, "0" )
6730Sstevel@tonic-gate 	    && (!charsetset) )
6740Sstevel@tonic-gate     {
6750Sstevel@tonic-gate 	/* zero option specified, so try to get default codepage
6760Sstevel@tonic-gate 	   this sucker is strdup'd immediately so it's OK to cast */
6770Sstevel@tonic-gate 	newcharset = (char *)ucnv_getDefaultName();
6780Sstevel@tonic-gate 	if (newcharset != NULL) {
6790Sstevel@tonic-gate 	    free( ldaptool_charset );
6800Sstevel@tonic-gate 	    /* the default codepage lives in ICU */
6810Sstevel@tonic-gate 	    ldaptool_charset = strdup(newcharset);
6820Sstevel@tonic-gate 	    if (ldaptool_charset == NULL) {
6830Sstevel@tonic-gate 		return strdup(src);
6840Sstevel@tonic-gate 	    }
6850Sstevel@tonic-gate 	}
6860Sstevel@tonic-gate 	charsetset = 1;
6870Sstevel@tonic-gate     }
6880Sstevel@tonic-gate     else
6890Sstevel@tonic-gate     if( strcmp( ldaptool_charset, "" ) && (!charsetset) )
6900Sstevel@tonic-gate     {
6910Sstevel@tonic-gate 	/* -i option specified with charset name */
6920Sstevel@tonic-gate         charsetset = 1;
6930Sstevel@tonic-gate     }
6940Sstevel@tonic-gate 
6950Sstevel@tonic-gate     /* do the preflight - get the size needed for the target buffer */
6960Sstevel@tonic-gate     outLen = (size_t) ucnv_convert( "utf-8", ldaptool_charset, NULL, 0, src,
6970Sstevel@tonic-gate                                       strlen( src ) * sizeof(char), &err);
6980Sstevel@tonic-gate 
6990Sstevel@tonic-gate     if ((err != U_BUFFER_OVERFLOW_ERROR) || (outLen == 0)) {
7000Sstevel@tonic-gate       /* default to just a copy of the string - this covers
7010Sstevel@tonic-gate          the case of an illegal charset also */
7020Sstevel@tonic-gate       return strdup(src);
7030Sstevel@tonic-gate     }
7040Sstevel@tonic-gate 
7050Sstevel@tonic-gate     utf8 =  (char *) malloc( outLen + 1);
7060Sstevel@tonic-gate     if( utf8 == NULL ) {
7070Sstevel@tonic-gate       /* if we're already out of memory, does strdup just return NULL? */
7080Sstevel@tonic-gate        return strdup(src);
7090Sstevel@tonic-gate     }
7100Sstevel@tonic-gate 
7110Sstevel@tonic-gate     /* do the actual conversion this time */
7120Sstevel@tonic-gate     err = U_ZERO_ERROR;
7130Sstevel@tonic-gate     resultLen = ucnv_convert( "utf-8", ldaptool_charset, utf8, (outLen + 1), src,
7140Sstevel@tonic-gate 		       strlen(src) * sizeof(char), &err );
7150Sstevel@tonic-gate 
7160Sstevel@tonic-gate     if (!U_SUCCESS(err)) {
7170Sstevel@tonic-gate       free(utf8);
7180Sstevel@tonic-gate       return strdup(src);
7190Sstevel@tonic-gate     }
7200Sstevel@tonic-gate 
7210Sstevel@tonic-gate #else
7220Sstevel@tonic-gate     utf8 = _convertor(src, FALSE);
7230Sstevel@tonic-gate     if( utf8 == NULL )
7240Sstevel@tonic-gate         utf8 = strdup(src);
7250Sstevel@tonic-gate #endif
7260Sstevel@tonic-gate 
7270Sstevel@tonic-gate     return utf8;
7280Sstevel@tonic-gate }
7290Sstevel@tonic-gate #endif /* HAVE_LIBICU */
7300Sstevel@tonic-gate 
7310Sstevel@tonic-gate #ifndef HAVE_LIBICU
7320Sstevel@tonic-gate #ifdef __cplusplus
7330Sstevel@tonic-gate }
7340Sstevel@tonic-gate #endif
7350Sstevel@tonic-gate #endif
736