xref: /illumos-gate/usr/src/cmd/ldap/common/convutf8.c (revision 55fea89d)
17c478bd9Sstevel@tonic-gate /*
2ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate /*
77c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the Netscape Public
87c478bd9Sstevel@tonic-gate  * License Version 1.1 (the "License"); you may not use this file
97c478bd9Sstevel@tonic-gate  * except in compliance with the License. You may obtain a copy of
107c478bd9Sstevel@tonic-gate  * the License at http://www.mozilla.org/NPL/
117c478bd9Sstevel@tonic-gate  *
127c478bd9Sstevel@tonic-gate  * Software distributed under the License is distributed on an "AS
137c478bd9Sstevel@tonic-gate  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
147c478bd9Sstevel@tonic-gate  * implied. See the License for the specific language governing
157c478bd9Sstevel@tonic-gate  * rights and limitations under the License.
167c478bd9Sstevel@tonic-gate  *
177c478bd9Sstevel@tonic-gate  * The Original Code is Mozilla Communicator client code, released
187c478bd9Sstevel@tonic-gate  * March 31, 1998.
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * The Initial Developer of the Original Code is Netscape
217c478bd9Sstevel@tonic-gate  * Communications Corporation. Portions created by Netscape are
227c478bd9Sstevel@tonic-gate  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
237c478bd9Sstevel@tonic-gate  * Rights Reserved.
247c478bd9Sstevel@tonic-gate  *
257c478bd9Sstevel@tonic-gate  * Contributor(s):
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <stdio.h>
297c478bd9Sstevel@tonic-gate #include <stdlib.h>
307c478bd9Sstevel@tonic-gate #include <string.h>
317c478bd9Sstevel@tonic-gate #include <locale.h>
327c478bd9Sstevel@tonic-gate #include <ctype.h>
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #ifndef HAVE_LIBICU
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
377c478bd9Sstevel@tonic-gate #include <errno.h>
387c478bd9Sstevel@tonic-gate #include <langinfo.h>
397c478bd9Sstevel@tonic-gate #include <iconv.h>
407c478bd9Sstevel@tonic-gate #endif
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate #ifdef __cplusplus
437c478bd9Sstevel@tonic-gate extern "C" {
447c478bd9Sstevel@tonic-gate #endif
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate extern char	*ldaptool_charset;
477c478bd9Sstevel@tonic-gate char		*ldaptool_convdir = NULL;
487c478bd9Sstevel@tonic-gate static		int charsetset = 0;
497c478bd9Sstevel@tonic-gate char		*ldaptool_local2UTF8( const char *src );
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
527c478bd9Sstevel@tonic-gate static char 	*ldaptool_convert( const char *src, const char *fcode,
537c478bd9Sstevel@tonic-gate 				const char *tcode);
547c478bd9Sstevel@tonic-gate char		*ldaptool_UTF82local( const char *src );
557c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
587c478bd9Sstevel@tonic-gate /*
597c478bd9Sstevel@tonic-gate  * ICU version always returns string, unless strdup fails.
607c478bd9Sstevel@tonic-gate  * As in ICU version, in case of error strdup(src)
617c478bd9Sstevel@tonic-gate  * Usually strdup(src) will be ASCII and legal anyways.
627c478bd9Sstevel@tonic-gate  */
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate static char *
ldaptool_convert(const char * src,const char * fcode,const char * tcode)657c478bd9Sstevel@tonic-gate ldaptool_convert( const char *src, const char *fcode,
667c478bd9Sstevel@tonic-gate 				 const char *tcode) {
677c478bd9Sstevel@tonic-gate     char	*dest, *tptr, *tmp;
68*55fea89dSDan Cross     const char	*fptr;
697c478bd9Sstevel@tonic-gate     iconv_t	cd;
707c478bd9Sstevel@tonic-gate     size_t	ileft, oleft, ret, size;
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate     if (src == NULL)
737c478bd9Sstevel@tonic-gate 	return (NULL);
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate     if (fcode == NULL || tcode == NULL)
767c478bd9Sstevel@tonic-gate 	return (strdup(src));
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate     if (strcasecmp(fcode, tcode) == 0)
797c478bd9Sstevel@tonic-gate 	return (strdup(src));
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate     if ((cd = iconv_open(tcode, fcode)) == (iconv_t)-1) {
827c478bd9Sstevel@tonic-gate 	/* conversion table not available */
837c478bd9Sstevel@tonic-gate 	return (strdup(src));
847c478bd9Sstevel@tonic-gate     }
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate     ileft = strlen(src);
877c478bd9Sstevel@tonic-gate     oleft = 2 * ileft;
887c478bd9Sstevel@tonic-gate     size = oleft;
897c478bd9Sstevel@tonic-gate     ret = -1;
907c478bd9Sstevel@tonic-gate     if ((dest = (char *)malloc(size)) == NULL) {
917c478bd9Sstevel@tonic-gate 	(void) iconv_close(cd);
927c478bd9Sstevel@tonic-gate 	/* maybe sizeof strlen(src) memory still exists */
937c478bd9Sstevel@tonic-gate 	return (strdup(src));
947c478bd9Sstevel@tonic-gate     }
957c478bd9Sstevel@tonic-gate     tptr = dest;
967c478bd9Sstevel@tonic-gate     fptr = src;
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate     for (;;) {
997c478bd9Sstevel@tonic-gate 	ret = iconv(cd, &fptr, &ileft, &tptr, &oleft);
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 	if (ret != (size_t)-1) {
1027c478bd9Sstevel@tonic-gate 		/*
1037c478bd9Sstevel@tonic-gate 		 * Success. Place 'cd' into its initial shift
1047c478bd9Sstevel@tonic-gate 		 * state before returning.
1057c478bd9Sstevel@tonic-gate 		 */
1067c478bd9Sstevel@tonic-gate 		if (fptr == NULL) /* already in initial state  */
1077c478bd9Sstevel@tonic-gate 			break;
1087c478bd9Sstevel@tonic-gate 		fptr = NULL;
1097c478bd9Sstevel@tonic-gate 		ileft = 0;
1107c478bd9Sstevel@tonic-gate 		continue;
1117c478bd9Sstevel@tonic-gate 	} if (errno == E2BIG) {
1127c478bd9Sstevel@tonic-gate 		/*
1137c478bd9Sstevel@tonic-gate 		 * Lack of space in output buffer.
1147c478bd9Sstevel@tonic-gate 		 * Hence double the size and retry.
1157c478bd9Sstevel@tonic-gate 		 * But before calling  iconv(), oleft
1167c478bd9Sstevel@tonic-gate 		 * and tptr have to re-adjusted, so that
1177c478bd9Sstevel@tonic-gate 		 * iconv() doesn't overwrite the data
1187c478bd9Sstevel@tonic-gate 		 * which has already been converted.
1197c478bd9Sstevel@tonic-gate 		 */
1207c478bd9Sstevel@tonic-gate 		oleft += size;
1217c478bd9Sstevel@tonic-gate 		size *= 2;
1227c478bd9Sstevel@tonic-gate 		if ((tmp = (char *) realloc(dest, size)) == NULL)
1237c478bd9Sstevel@tonic-gate 			break;
124*55fea89dSDan Cross 		tptr = tmp + (tptr - dest);
1257c478bd9Sstevel@tonic-gate 		dest = tmp;
1267c478bd9Sstevel@tonic-gate 		continue;
1277c478bd9Sstevel@tonic-gate 	} else {
1287c478bd9Sstevel@tonic-gate 		/* Other errors */
1297c478bd9Sstevel@tonic-gate 		break;
1307c478bd9Sstevel@tonic-gate 	}
1317c478bd9Sstevel@tonic-gate     }
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate     if (dest != NULL) {
1347c478bd9Sstevel@tonic-gate 	if (ret == -1) {
1357c478bd9Sstevel@tonic-gate     		/* Free malloc'ed memory on failure */
1367c478bd9Sstevel@tonic-gate 		free(dest);
1377c478bd9Sstevel@tonic-gate 		dest = NULL;
1387c478bd9Sstevel@tonic-gate 	} else if (oleft > 0) {
139*55fea89dSDan Cross 		/* NULL terminate the return value */
1407c478bd9Sstevel@tonic-gate 		*(dest + (size - oleft)) = '\0';
1417c478bd9Sstevel@tonic-gate 	} else {
142*55fea89dSDan Cross 		/* realloc one more byte and NULL terminate */
1437c478bd9Sstevel@tonic-gate 		if ((tmp = (char *) realloc(dest, size + 1)) == NULL) {
1447c478bd9Sstevel@tonic-gate 			free(dest);
1457c478bd9Sstevel@tonic-gate 			dest = NULL;
1467c478bd9Sstevel@tonic-gate 		} else {
1477c478bd9Sstevel@tonic-gate 			*(dest + size) = '\0';
1487c478bd9Sstevel@tonic-gate 		}
1497c478bd9Sstevel@tonic-gate 	}
1507c478bd9Sstevel@tonic-gate     }
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate     (void) iconv_close(cd);
1537c478bd9Sstevel@tonic-gate     if (dest == NULL) {
1547c478bd9Sstevel@tonic-gate 	/* last chance in case some other failure along the way occurs */
1557c478bd9Sstevel@tonic-gate 	return (strdup(src));
1567c478bd9Sstevel@tonic-gate     }
1577c478bd9Sstevel@tonic-gate     return (dest);
1587c478bd9Sstevel@tonic-gate }
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate char *
ldaptool_UTF82local(const char * src)1617c478bd9Sstevel@tonic-gate ldaptool_UTF82local( const char *src )
1627c478bd9Sstevel@tonic-gate {
1637c478bd9Sstevel@tonic-gate     char *to_code;
1647c478bd9Sstevel@tonic-gate     if ((to_code = nl_langinfo(CODESET)) == NULL)
1657c478bd9Sstevel@tonic-gate 	return (strdup(src));
1667c478bd9Sstevel@tonic-gate     return (ldaptool_convert(src, "UTF-8", (const char *)to_code));
1677c478bd9Sstevel@tonic-gate }
1687c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate char *
ldaptool_local2UTF8(const char * src)1717c478bd9Sstevel@tonic-gate ldaptool_local2UTF8( const char *src )
1727c478bd9Sstevel@tonic-gate {
1737c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
1747c478bd9Sstevel@tonic-gate     char *from_code;
1757c478bd9Sstevel@tonic-gate     if ((from_code = nl_langinfo(CODESET)) == NULL)
1767c478bd9Sstevel@tonic-gate 	return (strdup(src));
1777c478bd9Sstevel@tonic-gate     return (ldaptool_convert(src, (const char *)from_code, "UTF-8"));
1787c478bd9Sstevel@tonic-gate #else
1797c478bd9Sstevel@tonic-gate     char *utf8;
1807c478bd9Sstevel@tonic-gate     charsetset = 0;
1817c478bd9Sstevel@tonic-gate     if (src == NULL)
1827c478bd9Sstevel@tonic-gate     {
1837c478bd9Sstevel@tonic-gate 	return NULL;
1847c478bd9Sstevel@tonic-gate     }
1857c478bd9Sstevel@tonic-gate     utf8 = strdup(src);
1867c478bd9Sstevel@tonic-gate     return ( utf8 );
1877c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
1887c478bd9Sstevel@tonic-gate }
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate #else /* HAVE_LIBICU */
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate #include "unicode/utypes.h"
1937c478bd9Sstevel@tonic-gate #include "unicode/ucnv.h"
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate #define NSPR20
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate #ifdef XP_WIN32
1987c478bd9Sstevel@tonic-gate #define  VC_EXTRALEAN
1997c478bd9Sstevel@tonic-gate #include <afxwin.h>
2007c478bd9Sstevel@tonic-gate #include <winnls.h>
2017c478bd9Sstevel@tonic-gate #endif
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate extern char *ldaptool_charset;
2047c478bd9Sstevel@tonic-gate static int charsetset = 0;
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate extern "C" {
2077c478bd9Sstevel@tonic-gate char *ldaptool_convdir = NULL;
2087c478bd9Sstevel@tonic-gate char *ldaptool_local2UTF8( const char * );
2097c478bd9Sstevel@tonic-gate }
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate #ifndef XP_WIN32
2127c478bd9Sstevel@tonic-gate char * GetNormalizedLocaleName(void);
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate char *
2167c478bd9Sstevel@tonic-gate GetNormalizedLocaleName(void)
2177c478bd9Sstevel@tonic-gate {
2187c478bd9Sstevel@tonic-gate #ifdef _HPUX_SOURCE
219*55fea89dSDan Cross 
2207c478bd9Sstevel@tonic-gate     int    len;
2217c478bd9Sstevel@tonic-gate     char    *locale;
222*55fea89dSDan Cross 
2237c478bd9Sstevel@tonic-gate     locale = setlocale(LC_CTYPE, "");
2247c478bd9Sstevel@tonic-gate     if (locale && *locale) {
2257c478bd9Sstevel@tonic-gate         len = strlen(locale);
2267c478bd9Sstevel@tonic-gate     } else {
2277c478bd9Sstevel@tonic-gate         locale = "C";
2287c478bd9Sstevel@tonic-gate         len = 1;
2297c478bd9Sstevel@tonic-gate     }
230*55fea89dSDan Cross 
2317c478bd9Sstevel@tonic-gate     if ((!strncmp(locale, "/\x03:", 3)) &&
2327c478bd9Sstevel@tonic-gate         (!strcmp(&locale[len - 2], ";/"))) {
2337c478bd9Sstevel@tonic-gate         locale += 3;
2347c478bd9Sstevel@tonic-gate         len -= 5;
2357c478bd9Sstevel@tonic-gate     }
236*55fea89dSDan Cross 
2377c478bd9Sstevel@tonic-gate     locale = strdup(locale);
2387c478bd9Sstevel@tonic-gate     if (locale) {
2397c478bd9Sstevel@tonic-gate         locale[len] = 0;
2407c478bd9Sstevel@tonic-gate     }
241*55fea89dSDan Cross 
2427c478bd9Sstevel@tonic-gate     return locale;
243*55fea89dSDan Cross 
2447c478bd9Sstevel@tonic-gate #else
245*55fea89dSDan Cross 
2467c478bd9Sstevel@tonic-gate     char    *locale;
247*55fea89dSDan Cross 
2487c478bd9Sstevel@tonic-gate     locale = setlocale(LC_CTYPE, "");
2497c478bd9Sstevel@tonic-gate     if (locale && *locale) {
2507c478bd9Sstevel@tonic-gate         return strdup(locale);
2517c478bd9Sstevel@tonic-gate     }
252*55fea89dSDan Cross 
2537c478bd9Sstevel@tonic-gate     return strdup("C");
254*55fea89dSDan Cross 
2557c478bd9Sstevel@tonic-gate #endif
2567c478bd9Sstevel@tonic-gate }
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate #if defined(IRIX)
2597c478bd9Sstevel@tonic-gate const char *CHARCONVTABLE[] =
2607c478bd9Sstevel@tonic-gate {
2617c478bd9Sstevel@tonic-gate "! This table maps the host's locale names to IANA charsets",
2627c478bd9Sstevel@tonic-gate "!",
2637c478bd9Sstevel@tonic-gate "C:             ISO_8859-1:1987",
2647c478bd9Sstevel@tonic-gate "cs:            ISO_8859-2:1987",
2657c478bd9Sstevel@tonic-gate "da:            ISO_8859-1:1987",
2667c478bd9Sstevel@tonic-gate "de:            ISO_8859-1:1987",
2677c478bd9Sstevel@tonic-gate "de_AT:         ISO_8859-1:1987",
2687c478bd9Sstevel@tonic-gate "de_CH:         ISO_8859-1:1987",
2697c478bd9Sstevel@tonic-gate "en:            ISO_8859-1:1987",
2707c478bd9Sstevel@tonic-gate "en_AU:         ISO_8859-1:1987",
2717c478bd9Sstevel@tonic-gate "en_CA:         ISO_8859-1:1987",
2727c478bd9Sstevel@tonic-gate "en_TH:         ISO_8859-1:1987",
2737c478bd9Sstevel@tonic-gate "en_US:         ISO_8859-1:1987",
2747c478bd9Sstevel@tonic-gate "es:            ISO_8859-1:1987",
2757c478bd9Sstevel@tonic-gate "fi:            ISO_8859-1:1987",
2767c478bd9Sstevel@tonic-gate "fr:            ISO_8859-1:1987",
2777c478bd9Sstevel@tonic-gate "fr_BE:         ISO_8859-1:1987",
2787c478bd9Sstevel@tonic-gate "fr_CA:         ISO_8859-1:1987",
2797c478bd9Sstevel@tonic-gate "fr_CH:         ISO_8859-1:1987",
2807c478bd9Sstevel@tonic-gate "is:            ISO_8859-1:1987",
2817c478bd9Sstevel@tonic-gate "it:            ISO_8859-1:1987",
2827c478bd9Sstevel@tonic-gate "it_CH:         ISO_8859-1:1987",
2837c478bd9Sstevel@tonic-gate "ja_JP.EUC:     Extended_UNIX_Code_Packed_Format_for_Japanese",
2847c478bd9Sstevel@tonic-gate "ko_KR.euc:     EUC-KR",
2857c478bd9Sstevel@tonic-gate "nl:            ISO_8859-1:1987",
2867c478bd9Sstevel@tonic-gate "nl_BE:         ISO_8859-1:1987",
2877c478bd9Sstevel@tonic-gate "no:            ISO_8859-1:1987",
2887c478bd9Sstevel@tonic-gate "pl:            ISO_8859-2:1987",
2897c478bd9Sstevel@tonic-gate "pt:            ISO_8859-1:1987",
2907c478bd9Sstevel@tonic-gate "sh:            ISO_8859-2:1987",
2917c478bd9Sstevel@tonic-gate "sk:            ISO_8859-2:1987",
2927c478bd9Sstevel@tonic-gate "sv:            ISO_8859-1:1987",
2937c478bd9Sstevel@tonic-gate "zh_CN.ugb:     GB2312",
2947c478bd9Sstevel@tonic-gate "zh_TW.ucns:    cns11643_1",
2957c478bd9Sstevel@tonic-gate NULL
2967c478bd9Sstevel@tonic-gate };
2977c478bd9Sstevel@tonic-gate #elif defined(SOLARIS)
2987c478bd9Sstevel@tonic-gate const char *CHARCONVTABLE[] =
2997c478bd9Sstevel@tonic-gate {
3007c478bd9Sstevel@tonic-gate "! This table maps the host's locale names to IANA charsets",
3017c478bd9Sstevel@tonic-gate "!",
3027c478bd9Sstevel@tonic-gate "C:             ISO_8859-1:1987",
3037c478bd9Sstevel@tonic-gate "ja:            Extended_UNIX_Code_Packed_Format_for_Japanese",
3047c478bd9Sstevel@tonic-gate "ja_JP.EUC:     Extended_UNIX_Code_Packed_Format_for_Japanese",
3057c478bd9Sstevel@tonic-gate "ja_JP.PCK:     Shift_JIS",
3067c478bd9Sstevel@tonic-gate "en:		ISO_8859-1:1987",
3077c478bd9Sstevel@tonic-gate "en_AU:		ISO_8859-1:1987",
3087c478bd9Sstevel@tonic-gate "en_CA:		ISO_8859-1:1987",
3097c478bd9Sstevel@tonic-gate "en_UK:		ISO_8859-1:1987",
3107c478bd9Sstevel@tonic-gate "en_US:		ISO_8859-1:1987",
3117c478bd9Sstevel@tonic-gate "es:		ISO_8859-1:1987",
3127c478bd9Sstevel@tonic-gate "es_AR:		ISO_8859-1:1987",
3137c478bd9Sstevel@tonic-gate "es_BO:		ISO_8859-1:1987",
3147c478bd9Sstevel@tonic-gate "es_CL:		ISO_8859-1:1987",
3157c478bd9Sstevel@tonic-gate "es_CO:		ISO_8859-1:1987",
3167c478bd9Sstevel@tonic-gate "es_CR:		ISO_8859-1:1987",
3177c478bd9Sstevel@tonic-gate "es_EC:		ISO_8859-1:1987",
3187c478bd9Sstevel@tonic-gate "es_GT:		ISO_8859-1:1987",
3197c478bd9Sstevel@tonic-gate "es_MX:		ISO_8859-1:1987",
3207c478bd9Sstevel@tonic-gate "es_NI:		ISO_8859-1:1987",
3217c478bd9Sstevel@tonic-gate "es_PA:		ISO_8859-1:1987",
3227c478bd9Sstevel@tonic-gate "es_PE:		ISO_8859-1:1987",
3237c478bd9Sstevel@tonic-gate "es_PY:		ISO_8859-1:1987",
3247c478bd9Sstevel@tonic-gate "es_SV:		ISO_8859-1:1987",
3257c478bd9Sstevel@tonic-gate "es_UY:		ISO_8859-1:1987",
3267c478bd9Sstevel@tonic-gate "es_VE:		ISO_8859-1:1987",
3277c478bd9Sstevel@tonic-gate "fr:		ISO_8859-1:1987",
3287c478bd9Sstevel@tonic-gate "fr_BE:		ISO_8859-1:1987",
3297c478bd9Sstevel@tonic-gate "fr_CA:		ISO_8859-1:1987",
3307c478bd9Sstevel@tonic-gate "fr_CH:		ISO_8859-1:1987",
3317c478bd9Sstevel@tonic-gate "de:		ISO_8859-1:1987",
3327c478bd9Sstevel@tonic-gate "de_AT:		ISO_8859-1:1987",
3337c478bd9Sstevel@tonic-gate "de_CH:		ISO_8859-1:1987",
3347c478bd9Sstevel@tonic-gate "nl:		ISO_8859-1:1987",
3357c478bd9Sstevel@tonic-gate "nl_BE:		ISO_8859-1:1987",
3367c478bd9Sstevel@tonic-gate "it:		ISO_8859-1:1987",
3377c478bd9Sstevel@tonic-gate "sv:		ISO_8859-1:1987",
3387c478bd9Sstevel@tonic-gate "no:		ISO_8859-1:1987",
3397c478bd9Sstevel@tonic-gate "da:		ISO_8859-1:1987",
3407c478bd9Sstevel@tonic-gate "iso_8859_1:    ISO_8859-1:1987",
3417c478bd9Sstevel@tonic-gate "japanese:      Extended_UNIX_Code_Packed_Format_for_Japanese",
3427c478bd9Sstevel@tonic-gate "ko:            EUC-KR",
3437c478bd9Sstevel@tonic-gate "zh:            GB2312",
3447c478bd9Sstevel@tonic-gate "zh_TW:         cns11643_1",
3457c478bd9Sstevel@tonic-gate NULL
3467c478bd9Sstevel@tonic-gate };
3477c478bd9Sstevel@tonic-gate #elif defined(OSF1)
3487c478bd9Sstevel@tonic-gate const char *CHARCONVTABLE[] =
3497c478bd9Sstevel@tonic-gate {
3507c478bd9Sstevel@tonic-gate "! This table maps the host's locale names to IANA charsets",
3517c478bd9Sstevel@tonic-gate "!",
3527c478bd9Sstevel@tonic-gate "C:                     ISO_8859-1:1987",
3537c478bd9Sstevel@tonic-gate "cs_CZ.ISO8859-2:       ISO_8859-2:1987",
3547c478bd9Sstevel@tonic-gate "cs_CZ:                 ISO_8859-2:1987",
3557c478bd9Sstevel@tonic-gate "da_DK.ISO8859-1:       ISO_8859-1:1987",
3567c478bd9Sstevel@tonic-gate "de_CH.ISO8859-1:       ISO_8859-1:1987",
3577c478bd9Sstevel@tonic-gate "de_DE.ISO8859-1:       ISO_8859-1:1987",
3587c478bd9Sstevel@tonic-gate "en_GB.ISO8859-1:       ISO_8859-1:1987",
3597c478bd9Sstevel@tonic-gate "en_US.ISO8859-1:       ISO_8859-1:1987",
3607c478bd9Sstevel@tonic-gate "es_ES.ISO8859-1:       ISO_8859-1:1987",
3617c478bd9Sstevel@tonic-gate "fi_FI.ISO8859-1:       ISO_8859-1:1987",
3627c478bd9Sstevel@tonic-gate "fr_BE.ISO8859-1:       ISO_8859-1:1987",
3637c478bd9Sstevel@tonic-gate "fr_CA.ISO8859-1:       ISO_8859-1:1987",
3647c478bd9Sstevel@tonic-gate "fr_CH.ISO8859-1:       ISO_8859-1:1987",
3657c478bd9Sstevel@tonic-gate "fr_FR.ISO8859-1:       ISO_8859-1:1987",
3667c478bd9Sstevel@tonic-gate "hu_HU.ISO8859-2:       ISO_8859-2:1987",
3677c478bd9Sstevel@tonic-gate "hu_HU:                 ISO_8859-2:1987",
3687c478bd9Sstevel@tonic-gate "is_IS.ISO8859-1:       ISO_8859-1:1987",
3697c478bd9Sstevel@tonic-gate "it_IT.ISO8859-1:       ISO_8859-1:1987",
3707c478bd9Sstevel@tonic-gate "ja_JP.SJIS:            Shift_JIS",
3717c478bd9Sstevel@tonic-gate "ja_JP.eucJP:           Extended_UNIX_Code_Packed_Format_for_Japanese",
3727c478bd9Sstevel@tonic-gate "ja_JP:                 Extended_UNIX_Code_Packed_Format_for_Japanese",
3737c478bd9Sstevel@tonic-gate "ko_KR.eucKR:           EUC-KR",
3747c478bd9Sstevel@tonic-gate "ko_KR:                 EUC-KR",
3757c478bd9Sstevel@tonic-gate "nl_BE.ISO8859-1:       ISO_8859-1:1987",
3767c478bd9Sstevel@tonic-gate "nl_NL.ISO8859-1:       ISO_8859-1:1987",
3777c478bd9Sstevel@tonic-gate "no_NO.ISO8859-1:       ISO_8859-1:1987",
3787c478bd9Sstevel@tonic-gate "pl_PL.ISO8859-2:       ISO_8859-2:1987",
3797c478bd9Sstevel@tonic-gate "pl_PL:                 ISO_8859-2:1987",
3807c478bd9Sstevel@tonic-gate "pt_PT.ISO8859-1:       ISO_8859-1:1987",
3817c478bd9Sstevel@tonic-gate "sk_SK.ISO8859-2:       ISO_8859-2:1987",
3827c478bd9Sstevel@tonic-gate "sk_SK:                 ISO_8859-2:1987",
3837c478bd9Sstevel@tonic-gate "sv_SE.ISO8859-1:       ISO_8859-1:1987",
3847c478bd9Sstevel@tonic-gate "zh_CN:                 GB2312",
3857c478bd9Sstevel@tonic-gate "zh_HK.big5:            Big5",
3867c478bd9Sstevel@tonic-gate "zh_HK.eucTW:           cns11643_1",
3877c478bd9Sstevel@tonic-gate "zh_TW.big5:            Big5",
3887c478bd9Sstevel@tonic-gate "zh_TW.big5@chuyin:     Big5",
3897c478bd9Sstevel@tonic-gate "zh_TW.big5@radical:    Big5",
3907c478bd9Sstevel@tonic-gate "zh_TW.big5@stroke:     Big5",
3917c478bd9Sstevel@tonic-gate "zh_TW.eucTW:           cns11643_1",
3927c478bd9Sstevel@tonic-gate "zh_TW.eucTW@chuyin:    cns11643_1",
3937c478bd9Sstevel@tonic-gate "zh_TW.eucTW@radical:   cns11643_1",
3947c478bd9Sstevel@tonic-gate "zh_TW.eucTW@stroke:    cns11643_1",
3957c478bd9Sstevel@tonic-gate "zh_TW:                 cns11643_1",
3967c478bd9Sstevel@tonic-gate NULL
3977c478bd9Sstevel@tonic-gate };
3987c478bd9Sstevel@tonic-gate #elif defined(HPUX)
3997c478bd9Sstevel@tonic-gate const char *CHARCONVTABLE[] =
4007c478bd9Sstevel@tonic-gate {
4017c478bd9Sstevel@tonic-gate "! This table maps the host's locale names to IANA charsets",
4027c478bd9Sstevel@tonic-gate "!",
4037c478bd9Sstevel@tonic-gate "C:			ISO_8859-1:1987",
4047c478bd9Sstevel@tonic-gate "ja_JP:			Extended_UNIX_Code_Packed_Format_for_Japanese",
4057c478bd9Sstevel@tonic-gate "ja_JP.SJIS:		Shift_JIS",
4067c478bd9Sstevel@tonic-gate "ja_JP.eucJP:		Extended_UNIX_Code_Packed_Format_for_Japanese",
4077c478bd9Sstevel@tonic-gate "es_ES:			ISO_8859-1:1987",
4087c478bd9Sstevel@tonic-gate "es_ES.iso88591:	ISO_8859-1:1987",
4097c478bd9Sstevel@tonic-gate "sv_SE:			ISO_8859-1:1987",
4107c478bd9Sstevel@tonic-gate "sv_SE.iso88591:	ISO_8859-1:1987",
4117c478bd9Sstevel@tonic-gate "da_DK:			ISO_8859-1:1987",
4127c478bd9Sstevel@tonic-gate "da_DK.iso88591:	ISO_8859-1:1987",
4137c478bd9Sstevel@tonic-gate "nl_NL:			ISO_8859-1:1987",
4147c478bd9Sstevel@tonic-gate "nl_NL.iso88591:	ISO_8859-1:1987",
4157c478bd9Sstevel@tonic-gate "en:			ISO_8859-1:1987",
4167c478bd9Sstevel@tonic-gate "en_GB:			ISO_8859-1:1987",
4177c478bd9Sstevel@tonic-gate "en_GB.iso88591:	ISO_8859-1:1987",
4187c478bd9Sstevel@tonic-gate "en_US:			ISO_8859-1:1987",
4197c478bd9Sstevel@tonic-gate "en_US.iso88591:	ISO_8859-1:1987",
4207c478bd9Sstevel@tonic-gate "fi_FI:			ISO_8859-1:1987",
4217c478bd9Sstevel@tonic-gate "fi_FI.iso88591:	ISO_8859-1:1987",
4227c478bd9Sstevel@tonic-gate "fr_CA:			ISO_8859-1:1987",
4237c478bd9Sstevel@tonic-gate "fr_CA.iso88591:	ISO_8859-1:1987",
4247c478bd9Sstevel@tonic-gate "fr_FR:			ISO_8859-1:1987",
4257c478bd9Sstevel@tonic-gate "fr_FR.iso88591:	ISO_8859-1:1987",
4267c478bd9Sstevel@tonic-gate "de_DE:			ISO_8859-1:1987",
4277c478bd9Sstevel@tonic-gate "de_DE.iso88591:	ISO_8859-1:1987",
4287c478bd9Sstevel@tonic-gate "is_IS:			ISO_8859-1:1987",
4297c478bd9Sstevel@tonic-gate "is_IS.iso88591:	ISO_8859-1:1987",
4307c478bd9Sstevel@tonic-gate "it_IT:			ISO_8859-1:1987",
4317c478bd9Sstevel@tonic-gate "it_IT.iso88591:	ISO_8859-1:1987",
4327c478bd9Sstevel@tonic-gate "no_NO:			ISO_8859-1:1987",
4337c478bd9Sstevel@tonic-gate "no_NO.iso88591:	ISO_8859-1:1987",
4347c478bd9Sstevel@tonic-gate "pt_PT:			ISO_8859-1:1987",
4357c478bd9Sstevel@tonic-gate "pt_PT.iso88591:	ISO_8859-1:1987",
4367c478bd9Sstevel@tonic-gate "hu_HU:			ISO_8859-2:1987",
4377c478bd9Sstevel@tonic-gate "hu_HU.iso88592:	ISO_8859-2:1987",
4387c478bd9Sstevel@tonic-gate "cs_CZ:			ISO_8859-2:1987",
4397c478bd9Sstevel@tonic-gate "cs_CZ.iso88592:	ISO_8859-2:1987",
4407c478bd9Sstevel@tonic-gate "pl_PL:			ISO_8859-2:1987",
4417c478bd9Sstevel@tonic-gate "pl_PL.iso88592:	ISO_8859-2:1987",
4427c478bd9Sstevel@tonic-gate "ro_RO:			ISO_8859-2:1987",
4437c478bd9Sstevel@tonic-gate "ro_RO.iso88592:	ISO_8859-2:1987",
4447c478bd9Sstevel@tonic-gate "hr_HR:			ISO_8859-2:1987",
4457c478bd9Sstevel@tonic-gate "hr_HR.iso88592:	ISO_8859-2:1987",
4467c478bd9Sstevel@tonic-gate "sk_SK:			ISO_8859-2:1987",
4477c478bd9Sstevel@tonic-gate "sk_SK.iso88592:	ISO_8859-2:1987",
4487c478bd9Sstevel@tonic-gate "sl_SI:			ISO_8859-2:1987",
4497c478bd9Sstevel@tonic-gate "sl_SI.iso88592:	ISO_8859-2:1987",
4507c478bd9Sstevel@tonic-gate "american.iso88591:     ISO_8859-1:1987",
4517c478bd9Sstevel@tonic-gate "bulgarian:             ISO_8859-2:1987",
4527c478bd9Sstevel@tonic-gate "c-french.iso88591:     ISO_8859-1:1987",
4537c478bd9Sstevel@tonic-gate "chinese-s:             GB2312",
4547c478bd9Sstevel@tonic-gate "chinese-t.big5:                Big5",
4557c478bd9Sstevel@tonic-gate "czech:                 ISO_8859-2:1987",
4567c478bd9Sstevel@tonic-gate "danish.iso88591:       ISO_8859-1:1987",
4577c478bd9Sstevel@tonic-gate "dutch.iso88591:                ISO_8859-1:1987",
4587c478bd9Sstevel@tonic-gate "english.iso88591:      ISO_8859-1:1987",
4597c478bd9Sstevel@tonic-gate "finnish.iso88591:      ISO_8859-1:1987",
4607c478bd9Sstevel@tonic-gate "french.iso88591:       ISO_8859-1:1987",
4617c478bd9Sstevel@tonic-gate "german.iso88591:       ISO_8859-1:1987",
4627c478bd9Sstevel@tonic-gate "hungarian:             ISO_8859-2:1987",
4637c478bd9Sstevel@tonic-gate "icelandic.iso88591:    ISO_8859-1:1987",
4647c478bd9Sstevel@tonic-gate "italian.iso88591:      ISO_8859-1:1987",
4657c478bd9Sstevel@tonic-gate "japanese.euc:          Extended_UNIX_Code_Packed_Format_for_Japanese",
4667c478bd9Sstevel@tonic-gate "japanese:              Shift_JIS",
4677c478bd9Sstevel@tonic-gate "katakana:              Shift_JIS",
4687c478bd9Sstevel@tonic-gate "korean:                        EUC-KR",
4697c478bd9Sstevel@tonic-gate "norwegian.iso88591:    ISO_8859-1:1987",
4707c478bd9Sstevel@tonic-gate "polish:                        ISO_8859-2:1987",
4717c478bd9Sstevel@tonic-gate "portuguese.iso88591:   ISO_8859-1:1987",
4727c478bd9Sstevel@tonic-gate "rumanian:              ISO_8859-2:1987",
4737c478bd9Sstevel@tonic-gate "serbocroatian:         ISO_8859-2:1987",
4747c478bd9Sstevel@tonic-gate "slovene:               ISO_8859-2:1987",
4757c478bd9Sstevel@tonic-gate "spanish.iso88591:      ISO_8859-1:1987",
4767c478bd9Sstevel@tonic-gate "swedish.iso88591:      ISO_8859-1:1987",
4777c478bd9Sstevel@tonic-gate NULL
4787c478bd9Sstevel@tonic-gate };
4797c478bd9Sstevel@tonic-gate #elif defined(AIX)
4807c478bd9Sstevel@tonic-gate const char *CHARCONVTABLE[] =
4817c478bd9Sstevel@tonic-gate {
4827c478bd9Sstevel@tonic-gate "! This table maps the host's locale names to IANA charsets",
4837c478bd9Sstevel@tonic-gate "!",
4847c478bd9Sstevel@tonic-gate "C:                     ISO_8859-1:1987",
4857c478bd9Sstevel@tonic-gate "En_JP.IBM-932:         Shift_JIS",
4867c478bd9Sstevel@tonic-gate "En_JP:                 Shift_JIS",
4877c478bd9Sstevel@tonic-gate "Ja_JP.IBM-932:         Shift_JIS",
4887c478bd9Sstevel@tonic-gate "Ja_JP:                 Shift_JIS",
4897c478bd9Sstevel@tonic-gate "da_DK.ISO8859-1:       ISO_8859-1:1987",
4907c478bd9Sstevel@tonic-gate "da_DK:                 ISO_8859-1:1987",
4917c478bd9Sstevel@tonic-gate "de_CH.ISO8859-1:       ISO_8859-1:1987",
4927c478bd9Sstevel@tonic-gate "de_CH:                 ISO_8859-1:1987",
4937c478bd9Sstevel@tonic-gate "de_DE.ISO8859-1:       ISO_8859-1:1987",
4947c478bd9Sstevel@tonic-gate "de_DE:                 ISO_8859-1:1987",
4957c478bd9Sstevel@tonic-gate "en_GB.ISO8859-1:       ISO_8859-1:1987",
4967c478bd9Sstevel@tonic-gate "en_GB:                 ISO_8859-1:1987",
4977c478bd9Sstevel@tonic-gate "en_JP.IBM-eucJP:       Extended_UNIX_Code_Packed_Format_for_Japanese",
4987c478bd9Sstevel@tonic-gate "en_JP:                 Extended_UNIX_Code_Packed_Format_for_Japanese",
4997c478bd9Sstevel@tonic-gate "en_KR.IBM-eucKR:       EUC-KR",
5007c478bd9Sstevel@tonic-gate "en_KR:                 EUC-KR",
5017c478bd9Sstevel@tonic-gate "en_TW.IBM-eucTW:       cns11643_1",
5027c478bd9Sstevel@tonic-gate "en_TW:                 cns11643_1",
5037c478bd9Sstevel@tonic-gate "en_US.ISO8859-1:       ISO_8859-1:1987",
5047c478bd9Sstevel@tonic-gate "en_US:                 ISO_8859-1:1987",
5057c478bd9Sstevel@tonic-gate "es_ES.ISO8859-1:       ISO_8859-1:1987",
5067c478bd9Sstevel@tonic-gate "es_ES:                 ISO_8859-1:1987",
5077c478bd9Sstevel@tonic-gate "fi_FI.ISO8859-1:       ISO_8859-1:1987",
5087c478bd9Sstevel@tonic-gate "fi_FI:                 ISO_8859-1:1987",
5097c478bd9Sstevel@tonic-gate "fr_BE.ISO8859-1:       ISO_8859-1:1987",
5107c478bd9Sstevel@tonic-gate "fr_BE:                 ISO_8859-1:1987",
5117c478bd9Sstevel@tonic-gate "fr_CA.ISO8859-1:       ISO_8859-1:1987",
5127c478bd9Sstevel@tonic-gate "fr_CA:                 ISO_8859-1:1987",
5137c478bd9Sstevel@tonic-gate "fr_CH.ISO8859-1:       ISO_8859-1:1987",
5147c478bd9Sstevel@tonic-gate "fr_CH:                 ISO_8859-1:1987",
5157c478bd9Sstevel@tonic-gate "fr_FR.ISO8859-1:       ISO_8859-1:1987",
5167c478bd9Sstevel@tonic-gate "fr_FR:                 ISO_8859-1:1987",
5177c478bd9Sstevel@tonic-gate "is_IS.ISO8859-1:       ISO_8859-1:1987",
5187c478bd9Sstevel@tonic-gate "is_IS:                 ISO_8859-1:1987",
5197c478bd9Sstevel@tonic-gate "it_IT.ISO8859-1:       ISO_8859-1:1987",
5207c478bd9Sstevel@tonic-gate "it_IT:                 ISO_8859-1:1987",
5217c478bd9Sstevel@tonic-gate "ja_JP.IBM-eucJP:       Extended_UNIX_Code_Packed_Format_for_Japanese",
5227c478bd9Sstevel@tonic-gate "ja_JP:                 Extended_UNIX_Code_Packed_Format_for_Japanese",
5237c478bd9Sstevel@tonic-gate "ko_KR.IBM-eucKR:       EUC-KR",
5247c478bd9Sstevel@tonic-gate "ko_KR:                 EUC-KR",
5257c478bd9Sstevel@tonic-gate "nl_BE.ISO8859-1:       ISO_8859-1:1987",
5267c478bd9Sstevel@tonic-gate "nl_BE:                 ISO_8859-1:1987",
5277c478bd9Sstevel@tonic-gate "nl_NL.ISO8859-1:       ISO_8859-1:1987",
5287c478bd9Sstevel@tonic-gate "nl_NL:                 ISO_8859-1:1987",
5297c478bd9Sstevel@tonic-gate "no_NO.ISO8859-1:       ISO_8859-1:1987",
5307c478bd9Sstevel@tonic-gate "no_NO:                 ISO_8859-1:1987",
5317c478bd9Sstevel@tonic-gate "pt_PT.ISO8859-1:       ISO_8859-1:1987",
5327c478bd9Sstevel@tonic-gate "pt_PT:                 ISO_8859-1:1987",
5337c478bd9Sstevel@tonic-gate "sv_SE.ISO8859-1:       ISO_8859-1:1987",
5347c478bd9Sstevel@tonic-gate "sv_SE:                 ISO_8859-1:1987",
5357c478bd9Sstevel@tonic-gate "zh_TW.IBM-eucTW:       cns11643_1",
5367c478bd9Sstevel@tonic-gate "zh_TW:                 cns11643_1",
5377c478bd9Sstevel@tonic-gate NULL
5387c478bd9Sstevel@tonic-gate };
5397c478bd9Sstevel@tonic-gate #else   // sunos by default
5407c478bd9Sstevel@tonic-gate const char *CHARCONVTABLE[] =
5417c478bd9Sstevel@tonic-gate {
5427c478bd9Sstevel@tonic-gate "! This table maps the host's locale names to IANA charsets",
5437c478bd9Sstevel@tonic-gate "!",
5447c478bd9Sstevel@tonic-gate "C:             ISO_8859-1:1987",
5457c478bd9Sstevel@tonic-gate "de:            ISO_8859-1:1987",
5467c478bd9Sstevel@tonic-gate "en_US:         ISO_8859-1:1987",
5477c478bd9Sstevel@tonic-gate "es:            ISO_8859-1:1987",
5487c478bd9Sstevel@tonic-gate "fr:            ISO_8859-1:1987",
5497c478bd9Sstevel@tonic-gate "iso_8859_1:    ISO_8859-1:1987",
5507c478bd9Sstevel@tonic-gate "it:            ISO_8859-1:1987",
5517c478bd9Sstevel@tonic-gate "ja:            Extended_UNIX_Code_Packed_Format_for_Japanese",
5527c478bd9Sstevel@tonic-gate "ja_JP.EUC:     Extended_UNIX_Code_Packed_Format_for_Japanese",
5537c478bd9Sstevel@tonic-gate "japanese:      Extended_UNIX_Code_Packed_Format_for_Japanese",
5547c478bd9Sstevel@tonic-gate "ko:            EUC-KR",
5557c478bd9Sstevel@tonic-gate "sv:            ISO_8859-1:1987",
5567c478bd9Sstevel@tonic-gate "zh:            GB2312",
5577c478bd9Sstevel@tonic-gate "zh_TW:         cns11643_1",
5587c478bd9Sstevel@tonic-gate NULL
5597c478bd9Sstevel@tonic-gate };
5607c478bd9Sstevel@tonic-gate #endif
561*55fea89dSDan Cross 
5627c478bd9Sstevel@tonic-gate #define BSZ     256
563*55fea89dSDan Cross 
5647c478bd9Sstevel@tonic-gate char *
5657c478bd9Sstevel@tonic-gate GetCharsetFromLocale(char *locale)
5667c478bd9Sstevel@tonic-gate {
5677c478bd9Sstevel@tonic-gate     char *tmpcharset = NULL;
5687c478bd9Sstevel@tonic-gate     char buf[BSZ];
5697c478bd9Sstevel@tonic-gate     char *p;
5707c478bd9Sstevel@tonic-gate     const char *line;
5717c478bd9Sstevel@tonic-gate     int i=0;
572*55fea89dSDan Cross 
5737c478bd9Sstevel@tonic-gate     line = CHARCONVTABLE[i];
5747c478bd9Sstevel@tonic-gate     while (line != NULL)
5757c478bd9Sstevel@tonic-gate     {
5767c478bd9Sstevel@tonic-gate        if (*line == 0)
577*55fea89dSDan Cross        {
5787c478bd9Sstevel@tonic-gate           break;
579*55fea89dSDan Cross        }
580*55fea89dSDan Cross 
5817c478bd9Sstevel@tonic-gate        strcpy(buf, line);
5827c478bd9Sstevel@tonic-gate        line = CHARCONVTABLE[++i];
583*55fea89dSDan Cross 
5847c478bd9Sstevel@tonic-gate        if (strlen(buf) == 0 || buf[0] == '!')
585*55fea89dSDan Cross        {
5867c478bd9Sstevel@tonic-gate           continue;
587*55fea89dSDan Cross        }
5887c478bd9Sstevel@tonic-gate        p = strchr(buf, ':');
5897c478bd9Sstevel@tonic-gate        if (p == NULL)
590*55fea89dSDan Cross        {
5917c478bd9Sstevel@tonic-gate           tmpcharset = NULL;
5927c478bd9Sstevel@tonic-gate           break;
593*55fea89dSDan Cross        }
5947c478bd9Sstevel@tonic-gate        *p = 0;
5957c478bd9Sstevel@tonic-gate        if (strcmp(buf, locale) == 0) {
5967c478bd9Sstevel@tonic-gate           while (*++p == ' ' || *p == '\t')
5977c478bd9Sstevel@tonic-gate              ;
5987c478bd9Sstevel@tonic-gate           if (isalpha(*p)) {
5997c478bd9Sstevel@tonic-gate              tmpcharset = strdup(p);
6007c478bd9Sstevel@tonic-gate           } else
6017c478bd9Sstevel@tonic-gate              tmpcharset = NULL;
602*55fea89dSDan Cross 
6037c478bd9Sstevel@tonic-gate           break;
6047c478bd9Sstevel@tonic-gate        }
6057c478bd9Sstevel@tonic-gate     }
6067c478bd9Sstevel@tonic-gate     return tmpcharset;
6077c478bd9Sstevel@tonic-gate }
608*55fea89dSDan Cross 
6097c478bd9Sstevel@tonic-gate #endif /* Not defined XP_WIN32 */
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate #ifdef XP_WIN32
6127c478bd9Sstevel@tonic-gate char *_convertor(const char *instr, int bFromUTF8)
6137c478bd9Sstevel@tonic-gate {
6147c478bd9Sstevel@tonic-gate     char  *outstr = NULL;
6157c478bd9Sstevel@tonic-gate     int    inlen, wclen, outlen;
6167c478bd9Sstevel@tonic-gate     LPWSTR wcstr;
617*55fea89dSDan Cross 
6187c478bd9Sstevel@tonic-gate     if (instr == NULL)
6197c478bd9Sstevel@tonic-gate             return NULL;
6207c478bd9Sstevel@tonic-gate 
6217c478bd9Sstevel@tonic-gate     if ((inlen = strlen(instr)) <= 0)
6227c478bd9Sstevel@tonic-gate             return NULL;
623*55fea89dSDan Cross 
6247c478bd9Sstevel@tonic-gate     /* output never becomes longer than input,
6257c478bd9Sstevel@tonic-gate      * thus we don't have to ask for the length
6267c478bd9Sstevel@tonic-gate      */
6277c478bd9Sstevel@tonic-gate     wcstr = (LPWSTR) malloc( sizeof( WCHAR ) * (inlen+1) );
6287c478bd9Sstevel@tonic-gate     if (!wcstr)
6297c478bd9Sstevel@tonic-gate         return NULL;
630*55fea89dSDan Cross 
6317c478bd9Sstevel@tonic-gate     wclen = MultiByteToWideChar(bFromUTF8 ? CP_UTF8 : CP_ACP, 0, instr,
6327c478bd9Sstevel@tonic-gate                                  inlen, wcstr, inlen);
6337c478bd9Sstevel@tonic-gate     outlen = WideCharToMultiByte(bFromUTF8 ? CP_ACP : CP_UTF8, 0, wcstr,
6347c478bd9Sstevel@tonic-gate                                   wclen, NULL, 0, NULL, NULL);
635*55fea89dSDan Cross 
6367c478bd9Sstevel@tonic-gate     if (outlen > 0) {
6377c478bd9Sstevel@tonic-gate         outstr = (char *) malloc(outlen + 2);
6387c478bd9Sstevel@tonic-gate         outlen = WideCharToMultiByte(bFromUTF8 ? CP_ACP : CP_UTF8, 0, wcstr,
6397c478bd9Sstevel@tonic-gate                                       wclen, outstr, outlen, NULL, NULL);
6407c478bd9Sstevel@tonic-gate         if (outlen > 0)
6417c478bd9Sstevel@tonic-gate             *(outstr+outlen) = _T('\0');
6427c478bd9Sstevel@tonic-gate         else
6437c478bd9Sstevel@tonic-gate             return NULL;
6447c478bd9Sstevel@tonic-gate     }
6457c478bd9Sstevel@tonic-gate     free( wcstr );
6467c478bd9Sstevel@tonic-gate     return outstr;
6477c478bd9Sstevel@tonic-gate }
6487c478bd9Sstevel@tonic-gate #endif
6497c478bd9Sstevel@tonic-gate 
6507c478bd9Sstevel@tonic-gate char *
6517c478bd9Sstevel@tonic-gate ldaptool_local2UTF8( const char *src )
6527c478bd9Sstevel@tonic-gate {
6537c478bd9Sstevel@tonic-gate     char *utf8;
6547c478bd9Sstevel@tonic-gate #ifndef XP_WIN32
6557c478bd9Sstevel@tonic-gate     char *locale, *newcharset;
6567c478bd9Sstevel@tonic-gate     size_t outLen, resultLen;
6577c478bd9Sstevel@tonic-gate     UErrorCode err = U_ZERO_ERROR;
6587c478bd9Sstevel@tonic-gate     UConverter *cnv;
659*55fea89dSDan Cross 
6607c478bd9Sstevel@tonic-gate     if (src == NULL)
6617c478bd9Sstevel@tonic-gate     {
6627c478bd9Sstevel@tonic-gate       return NULL;
6637c478bd9Sstevel@tonic-gate     }
664*55fea89dSDan Cross     else if (*src == 0 || (ldaptool_charset == NULL)
6657c478bd9Sstevel@tonic-gate 	     || (!strcmp( ldaptool_charset, "" )))
6667c478bd9Sstevel@tonic-gate     {
6677c478bd9Sstevel@tonic-gate 	/* no option specified, so assume it's already in utf-8 */
6687c478bd9Sstevel@tonic-gate         utf8 = strdup(src);
6697c478bd9Sstevel@tonic-gate         return utf8;
6707c478bd9Sstevel@tonic-gate     }
671*55fea89dSDan Cross 
6727c478bd9Sstevel@tonic-gate     if( !strcmp( ldaptool_charset, "0" )
6737c478bd9Sstevel@tonic-gate 	    && (!charsetset) )
6747c478bd9Sstevel@tonic-gate     {
6757c478bd9Sstevel@tonic-gate 	/* zero option specified, so try to get default codepage
6767c478bd9Sstevel@tonic-gate 	   this sucker is strdup'd immediately so it's OK to cast */
6777c478bd9Sstevel@tonic-gate 	newcharset = (char *)ucnv_getDefaultName();
6787c478bd9Sstevel@tonic-gate 	if (newcharset != NULL) {
6797c478bd9Sstevel@tonic-gate 	    free( ldaptool_charset );
6807c478bd9Sstevel@tonic-gate 	    /* the default codepage lives in ICU */
6817c478bd9Sstevel@tonic-gate 	    ldaptool_charset = strdup(newcharset);
6827c478bd9Sstevel@tonic-gate 	    if (ldaptool_charset == NULL) {
6837c478bd9Sstevel@tonic-gate 		return strdup(src);
684*55fea89dSDan Cross 	    }
6857c478bd9Sstevel@tonic-gate 	}
6867c478bd9Sstevel@tonic-gate 	charsetset = 1;
6877c478bd9Sstevel@tonic-gate     }
6887c478bd9Sstevel@tonic-gate     else
6897c478bd9Sstevel@tonic-gate     if( strcmp( ldaptool_charset, "" ) && (!charsetset) )
6907c478bd9Sstevel@tonic-gate     {
6917c478bd9Sstevel@tonic-gate 	/* -i option specified with charset name */
6927c478bd9Sstevel@tonic-gate         charsetset = 1;
6937c478bd9Sstevel@tonic-gate     }
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate     /* do the preflight - get the size needed for the target buffer */
6967c478bd9Sstevel@tonic-gate     outLen = (size_t) ucnv_convert( "utf-8", ldaptool_charset, NULL, 0, src,
697*55fea89dSDan Cross                                       strlen( src ) * sizeof(char), &err);
6987c478bd9Sstevel@tonic-gate 
6997c478bd9Sstevel@tonic-gate     if ((err != U_BUFFER_OVERFLOW_ERROR) || (outLen == 0)) {
7007c478bd9Sstevel@tonic-gate       /* default to just a copy of the string - this covers
7017c478bd9Sstevel@tonic-gate          the case of an illegal charset also */
7027c478bd9Sstevel@tonic-gate       return strdup(src);
7037c478bd9Sstevel@tonic-gate     }
7047c478bd9Sstevel@tonic-gate 
705*55fea89dSDan Cross     utf8 =  (char *) malloc( outLen + 1);
7067c478bd9Sstevel@tonic-gate     if( utf8 == NULL ) {
7077c478bd9Sstevel@tonic-gate       /* if we're already out of memory, does strdup just return NULL? */
7087c478bd9Sstevel@tonic-gate        return strdup(src);
7097c478bd9Sstevel@tonic-gate     }
7107c478bd9Sstevel@tonic-gate 
7117c478bd9Sstevel@tonic-gate     /* do the actual conversion this time */
7127c478bd9Sstevel@tonic-gate     err = U_ZERO_ERROR;
713*55fea89dSDan Cross     resultLen = ucnv_convert( "utf-8", ldaptool_charset, utf8, (outLen + 1), src,
714*55fea89dSDan Cross 		       strlen(src) * sizeof(char), &err );
7157c478bd9Sstevel@tonic-gate 
7167c478bd9Sstevel@tonic-gate     if (!U_SUCCESS(err)) {
7177c478bd9Sstevel@tonic-gate       free(utf8);
7187c478bd9Sstevel@tonic-gate       return strdup(src);
7197c478bd9Sstevel@tonic-gate     }
720*55fea89dSDan Cross 
7217c478bd9Sstevel@tonic-gate #else
7227c478bd9Sstevel@tonic-gate     utf8 = _convertor(src, FALSE);
7237c478bd9Sstevel@tonic-gate     if( utf8 == NULL )
7247c478bd9Sstevel@tonic-gate         utf8 = strdup(src);
7257c478bd9Sstevel@tonic-gate #endif
726*55fea89dSDan Cross 
7277c478bd9Sstevel@tonic-gate     return utf8;
7287c478bd9Sstevel@tonic-gate }
7297c478bd9Sstevel@tonic-gate #endif /* HAVE_LIBICU */
7307c478bd9Sstevel@tonic-gate 
7317c478bd9Sstevel@tonic-gate #ifndef HAVE_LIBICU
7327c478bd9Sstevel@tonic-gate #ifdef __cplusplus
7337c478bd9Sstevel@tonic-gate }
7347c478bd9Sstevel@tonic-gate #endif
7357c478bd9Sstevel@tonic-gate #endif
736