xref: /titanic_54/usr/src/cmd/ldap/common/convutf8.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
3*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
4*7c478bd9Sstevel@tonic-gate  */
5*7c478bd9Sstevel@tonic-gate 
6*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
7*7c478bd9Sstevel@tonic-gate 
8*7c478bd9Sstevel@tonic-gate /*
9*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the Netscape Public
10*7c478bd9Sstevel@tonic-gate  * License Version 1.1 (the "License"); you may not use this file
11*7c478bd9Sstevel@tonic-gate  * except in compliance with the License. You may obtain a copy of
12*7c478bd9Sstevel@tonic-gate  * the License at http://www.mozilla.org/NPL/
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * Software distributed under the License is distributed on an "AS
15*7c478bd9Sstevel@tonic-gate  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
16*7c478bd9Sstevel@tonic-gate  * implied. See the License for the specific language governing
17*7c478bd9Sstevel@tonic-gate  * rights and limitations under the License.
18*7c478bd9Sstevel@tonic-gate  *
19*7c478bd9Sstevel@tonic-gate  * The Original Code is Mozilla Communicator client code, released
20*7c478bd9Sstevel@tonic-gate  * March 31, 1998.
21*7c478bd9Sstevel@tonic-gate  *
22*7c478bd9Sstevel@tonic-gate  * The Initial Developer of the Original Code is Netscape
23*7c478bd9Sstevel@tonic-gate  * Communications Corporation. Portions created by Netscape are
24*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
25*7c478bd9Sstevel@tonic-gate  * Rights Reserved.
26*7c478bd9Sstevel@tonic-gate  *
27*7c478bd9Sstevel@tonic-gate  * Contributor(s):
28*7c478bd9Sstevel@tonic-gate  */
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #include <stdio.h>
31*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
32*7c478bd9Sstevel@tonic-gate #include <string.h>
33*7c478bd9Sstevel@tonic-gate #include <locale.h>
34*7c478bd9Sstevel@tonic-gate #include <ctype.h>
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate #ifndef HAVE_LIBICU
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
39*7c478bd9Sstevel@tonic-gate #include <errno.h>
40*7c478bd9Sstevel@tonic-gate #include <langinfo.h>
41*7c478bd9Sstevel@tonic-gate #include <iconv.h>
42*7c478bd9Sstevel@tonic-gate #endif
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus
45*7c478bd9Sstevel@tonic-gate extern "C" {
46*7c478bd9Sstevel@tonic-gate #endif
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate extern char	*ldaptool_charset;
49*7c478bd9Sstevel@tonic-gate char		*ldaptool_convdir = NULL;
50*7c478bd9Sstevel@tonic-gate static		int charsetset = 0;
51*7c478bd9Sstevel@tonic-gate char		*ldaptool_local2UTF8( const char *src );
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
54*7c478bd9Sstevel@tonic-gate static char 	*ldaptool_convert( const char *src, const char *fcode,
55*7c478bd9Sstevel@tonic-gate 				const char *tcode);
56*7c478bd9Sstevel@tonic-gate char		*ldaptool_UTF82local( const char *src );
57*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
58*7c478bd9Sstevel@tonic-gate 
59*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
60*7c478bd9Sstevel@tonic-gate /*
61*7c478bd9Sstevel@tonic-gate  * ICU version always returns string, unless strdup fails.
62*7c478bd9Sstevel@tonic-gate  * As in ICU version, in case of error strdup(src)
63*7c478bd9Sstevel@tonic-gate  * Usually strdup(src) will be ASCII and legal anyways.
64*7c478bd9Sstevel@tonic-gate  */
65*7c478bd9Sstevel@tonic-gate 
66*7c478bd9Sstevel@tonic-gate static char *
67*7c478bd9Sstevel@tonic-gate ldaptool_convert( const char *src, const char *fcode,
68*7c478bd9Sstevel@tonic-gate 				 const char *tcode) {
69*7c478bd9Sstevel@tonic-gate     char	*dest, *tptr, *tmp;
70*7c478bd9Sstevel@tonic-gate     const char	*fptr;
71*7c478bd9Sstevel@tonic-gate     iconv_t	cd;
72*7c478bd9Sstevel@tonic-gate     size_t	ileft, oleft, ret, size;
73*7c478bd9Sstevel@tonic-gate 
74*7c478bd9Sstevel@tonic-gate     if (src == NULL)
75*7c478bd9Sstevel@tonic-gate 	return (NULL);
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate     if (fcode == NULL || tcode == NULL)
78*7c478bd9Sstevel@tonic-gate 	return (strdup(src));
79*7c478bd9Sstevel@tonic-gate 
80*7c478bd9Sstevel@tonic-gate     if (strcasecmp(fcode, tcode) == 0)
81*7c478bd9Sstevel@tonic-gate 	return (strdup(src));
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate     if ((cd = iconv_open(tcode, fcode)) == (iconv_t)-1) {
84*7c478bd9Sstevel@tonic-gate 	/* conversion table not available */
85*7c478bd9Sstevel@tonic-gate 	return (strdup(src));
86*7c478bd9Sstevel@tonic-gate     }
87*7c478bd9Sstevel@tonic-gate 
88*7c478bd9Sstevel@tonic-gate     ileft = strlen(src);
89*7c478bd9Sstevel@tonic-gate     oleft = 2 * ileft;
90*7c478bd9Sstevel@tonic-gate     size = oleft;
91*7c478bd9Sstevel@tonic-gate     ret = -1;
92*7c478bd9Sstevel@tonic-gate     if ((dest = (char *)malloc(size)) == NULL) {
93*7c478bd9Sstevel@tonic-gate 	(void) iconv_close(cd);
94*7c478bd9Sstevel@tonic-gate 	/* maybe sizeof strlen(src) memory still exists */
95*7c478bd9Sstevel@tonic-gate 	return (strdup(src));
96*7c478bd9Sstevel@tonic-gate     }
97*7c478bd9Sstevel@tonic-gate     tptr = dest;
98*7c478bd9Sstevel@tonic-gate     fptr = src;
99*7c478bd9Sstevel@tonic-gate 
100*7c478bd9Sstevel@tonic-gate     for (;;) {
101*7c478bd9Sstevel@tonic-gate 	ret = iconv(cd, &fptr, &ileft, &tptr, &oleft);
102*7c478bd9Sstevel@tonic-gate 
103*7c478bd9Sstevel@tonic-gate 	if (ret != (size_t)-1) {
104*7c478bd9Sstevel@tonic-gate 		/*
105*7c478bd9Sstevel@tonic-gate 		 * Success. Place 'cd' into its initial shift
106*7c478bd9Sstevel@tonic-gate 		 * state before returning.
107*7c478bd9Sstevel@tonic-gate 		 */
108*7c478bd9Sstevel@tonic-gate 		if (fptr == NULL) /* already in initial state  */
109*7c478bd9Sstevel@tonic-gate 			break;
110*7c478bd9Sstevel@tonic-gate 		fptr = NULL;
111*7c478bd9Sstevel@tonic-gate 		ileft = 0;
112*7c478bd9Sstevel@tonic-gate 		continue;
113*7c478bd9Sstevel@tonic-gate 	} if (errno == E2BIG) {
114*7c478bd9Sstevel@tonic-gate 		/*
115*7c478bd9Sstevel@tonic-gate 		 * Lack of space in output buffer.
116*7c478bd9Sstevel@tonic-gate 		 * Hence double the size and retry.
117*7c478bd9Sstevel@tonic-gate 		 * But before calling  iconv(), oleft
118*7c478bd9Sstevel@tonic-gate 		 * and tptr have to re-adjusted, so that
119*7c478bd9Sstevel@tonic-gate 		 * iconv() doesn't overwrite the data
120*7c478bd9Sstevel@tonic-gate 		 * which has already been converted.
121*7c478bd9Sstevel@tonic-gate 		 */
122*7c478bd9Sstevel@tonic-gate 		oleft += size;
123*7c478bd9Sstevel@tonic-gate 		size *= 2;
124*7c478bd9Sstevel@tonic-gate 		if ((tmp = (char *) realloc(dest, size)) == NULL)
125*7c478bd9Sstevel@tonic-gate 			break;
126*7c478bd9Sstevel@tonic-gate 		tptr = tmp + (tptr - dest);
127*7c478bd9Sstevel@tonic-gate 		dest = tmp;
128*7c478bd9Sstevel@tonic-gate 		continue;
129*7c478bd9Sstevel@tonic-gate 	} else {
130*7c478bd9Sstevel@tonic-gate 		/* Other errors */
131*7c478bd9Sstevel@tonic-gate 		break;
132*7c478bd9Sstevel@tonic-gate 	}
133*7c478bd9Sstevel@tonic-gate     }
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate     if (dest != NULL) {
136*7c478bd9Sstevel@tonic-gate 	if (ret == -1) {
137*7c478bd9Sstevel@tonic-gate     		/* Free malloc'ed memory on failure */
138*7c478bd9Sstevel@tonic-gate 		free(dest);
139*7c478bd9Sstevel@tonic-gate 		dest = NULL;
140*7c478bd9Sstevel@tonic-gate 	} else if (oleft > 0) {
141*7c478bd9Sstevel@tonic-gate 		/* NULL terminate the return value */
142*7c478bd9Sstevel@tonic-gate 		*(dest + (size - oleft)) = '\0';
143*7c478bd9Sstevel@tonic-gate 	} else {
144*7c478bd9Sstevel@tonic-gate 		/* realloc one more byte and NULL terminate */
145*7c478bd9Sstevel@tonic-gate 		if ((tmp = (char *) realloc(dest, size + 1)) == NULL) {
146*7c478bd9Sstevel@tonic-gate 			free(dest);
147*7c478bd9Sstevel@tonic-gate 			dest = NULL;
148*7c478bd9Sstevel@tonic-gate 		} else {
149*7c478bd9Sstevel@tonic-gate 			*(dest + size) = '\0';
150*7c478bd9Sstevel@tonic-gate 		}
151*7c478bd9Sstevel@tonic-gate 	}
152*7c478bd9Sstevel@tonic-gate     }
153*7c478bd9Sstevel@tonic-gate 
154*7c478bd9Sstevel@tonic-gate     (void) iconv_close(cd);
155*7c478bd9Sstevel@tonic-gate     if (dest == NULL) {
156*7c478bd9Sstevel@tonic-gate 	/* last chance in case some other failure along the way occurs */
157*7c478bd9Sstevel@tonic-gate 	return (strdup(src));
158*7c478bd9Sstevel@tonic-gate     }
159*7c478bd9Sstevel@tonic-gate     return (dest);
160*7c478bd9Sstevel@tonic-gate }
161*7c478bd9Sstevel@tonic-gate 
162*7c478bd9Sstevel@tonic-gate char *
163*7c478bd9Sstevel@tonic-gate ldaptool_UTF82local( const char *src )
164*7c478bd9Sstevel@tonic-gate {
165*7c478bd9Sstevel@tonic-gate     char *to_code;
166*7c478bd9Sstevel@tonic-gate     if ((to_code = nl_langinfo(CODESET)) == NULL)
167*7c478bd9Sstevel@tonic-gate 	return (strdup(src));
168*7c478bd9Sstevel@tonic-gate     return (ldaptool_convert(src, "UTF-8", (const char *)to_code));
169*7c478bd9Sstevel@tonic-gate }
170*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
171*7c478bd9Sstevel@tonic-gate 
172*7c478bd9Sstevel@tonic-gate char *
173*7c478bd9Sstevel@tonic-gate ldaptool_local2UTF8( const char *src )
174*7c478bd9Sstevel@tonic-gate {
175*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
176*7c478bd9Sstevel@tonic-gate     char *from_code;
177*7c478bd9Sstevel@tonic-gate     if ((from_code = nl_langinfo(CODESET)) == NULL)
178*7c478bd9Sstevel@tonic-gate 	return (strdup(src));
179*7c478bd9Sstevel@tonic-gate     return (ldaptool_convert(src, (const char *)from_code, "UTF-8"));
180*7c478bd9Sstevel@tonic-gate #else
181*7c478bd9Sstevel@tonic-gate     char *utf8;
182*7c478bd9Sstevel@tonic-gate     charsetset = 0;
183*7c478bd9Sstevel@tonic-gate     if (src == NULL)
184*7c478bd9Sstevel@tonic-gate     {
185*7c478bd9Sstevel@tonic-gate 	return NULL;
186*7c478bd9Sstevel@tonic-gate     }
187*7c478bd9Sstevel@tonic-gate     utf8 = strdup(src);
188*7c478bd9Sstevel@tonic-gate     return ( utf8 );
189*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
190*7c478bd9Sstevel@tonic-gate }
191*7c478bd9Sstevel@tonic-gate 
192*7c478bd9Sstevel@tonic-gate #else /* HAVE_LIBICU */
193*7c478bd9Sstevel@tonic-gate 
194*7c478bd9Sstevel@tonic-gate #include "unicode/utypes.h"
195*7c478bd9Sstevel@tonic-gate #include "unicode/ucnv.h"
196*7c478bd9Sstevel@tonic-gate 
197*7c478bd9Sstevel@tonic-gate #define NSPR20
198*7c478bd9Sstevel@tonic-gate 
199*7c478bd9Sstevel@tonic-gate #ifdef XP_WIN32
200*7c478bd9Sstevel@tonic-gate #define  VC_EXTRALEAN
201*7c478bd9Sstevel@tonic-gate #include <afxwin.h>
202*7c478bd9Sstevel@tonic-gate #include <winnls.h>
203*7c478bd9Sstevel@tonic-gate #endif
204*7c478bd9Sstevel@tonic-gate 
205*7c478bd9Sstevel@tonic-gate extern char *ldaptool_charset;
206*7c478bd9Sstevel@tonic-gate static int charsetset = 0;
207*7c478bd9Sstevel@tonic-gate 
208*7c478bd9Sstevel@tonic-gate extern "C" {
209*7c478bd9Sstevel@tonic-gate char *ldaptool_convdir = NULL;
210*7c478bd9Sstevel@tonic-gate char *ldaptool_local2UTF8( const char * );
211*7c478bd9Sstevel@tonic-gate }
212*7c478bd9Sstevel@tonic-gate 
213*7c478bd9Sstevel@tonic-gate #ifndef XP_WIN32
214*7c478bd9Sstevel@tonic-gate char * GetNormalizedLocaleName(void);
215*7c478bd9Sstevel@tonic-gate 
216*7c478bd9Sstevel@tonic-gate 
217*7c478bd9Sstevel@tonic-gate char *
218*7c478bd9Sstevel@tonic-gate GetNormalizedLocaleName(void)
219*7c478bd9Sstevel@tonic-gate {
220*7c478bd9Sstevel@tonic-gate #ifdef _HPUX_SOURCE
221*7c478bd9Sstevel@tonic-gate 
222*7c478bd9Sstevel@tonic-gate     int    len;
223*7c478bd9Sstevel@tonic-gate     char    *locale;
224*7c478bd9Sstevel@tonic-gate 
225*7c478bd9Sstevel@tonic-gate     locale = setlocale(LC_CTYPE, "");
226*7c478bd9Sstevel@tonic-gate     if (locale && *locale) {
227*7c478bd9Sstevel@tonic-gate         len = strlen(locale);
228*7c478bd9Sstevel@tonic-gate     } else {
229*7c478bd9Sstevel@tonic-gate         locale = "C";
230*7c478bd9Sstevel@tonic-gate         len = 1;
231*7c478bd9Sstevel@tonic-gate     }
232*7c478bd9Sstevel@tonic-gate 
233*7c478bd9Sstevel@tonic-gate     if ((!strncmp(locale, "/\x03:", 3)) &&
234*7c478bd9Sstevel@tonic-gate         (!strcmp(&locale[len - 2], ";/"))) {
235*7c478bd9Sstevel@tonic-gate         locale += 3;
236*7c478bd9Sstevel@tonic-gate         len -= 5;
237*7c478bd9Sstevel@tonic-gate     }
238*7c478bd9Sstevel@tonic-gate 
239*7c478bd9Sstevel@tonic-gate     locale = strdup(locale);
240*7c478bd9Sstevel@tonic-gate     if (locale) {
241*7c478bd9Sstevel@tonic-gate         locale[len] = 0;
242*7c478bd9Sstevel@tonic-gate     }
243*7c478bd9Sstevel@tonic-gate 
244*7c478bd9Sstevel@tonic-gate     return locale;
245*7c478bd9Sstevel@tonic-gate 
246*7c478bd9Sstevel@tonic-gate #else
247*7c478bd9Sstevel@tonic-gate 
248*7c478bd9Sstevel@tonic-gate     char    *locale;
249*7c478bd9Sstevel@tonic-gate 
250*7c478bd9Sstevel@tonic-gate     locale = setlocale(LC_CTYPE, "");
251*7c478bd9Sstevel@tonic-gate     if (locale && *locale) {
252*7c478bd9Sstevel@tonic-gate         return strdup(locale);
253*7c478bd9Sstevel@tonic-gate     }
254*7c478bd9Sstevel@tonic-gate 
255*7c478bd9Sstevel@tonic-gate     return strdup("C");
256*7c478bd9Sstevel@tonic-gate 
257*7c478bd9Sstevel@tonic-gate #endif
258*7c478bd9Sstevel@tonic-gate }
259*7c478bd9Sstevel@tonic-gate 
260*7c478bd9Sstevel@tonic-gate #if defined(IRIX)
261*7c478bd9Sstevel@tonic-gate const char *CHARCONVTABLE[] =
262*7c478bd9Sstevel@tonic-gate {
263*7c478bd9Sstevel@tonic-gate "! This table maps the host's locale names to IANA charsets",
264*7c478bd9Sstevel@tonic-gate "!",
265*7c478bd9Sstevel@tonic-gate "C:             ISO_8859-1:1987",
266*7c478bd9Sstevel@tonic-gate "cs:            ISO_8859-2:1987",
267*7c478bd9Sstevel@tonic-gate "da:            ISO_8859-1:1987",
268*7c478bd9Sstevel@tonic-gate "de:            ISO_8859-1:1987",
269*7c478bd9Sstevel@tonic-gate "de_AT:         ISO_8859-1:1987",
270*7c478bd9Sstevel@tonic-gate "de_CH:         ISO_8859-1:1987",
271*7c478bd9Sstevel@tonic-gate "en:            ISO_8859-1:1987",
272*7c478bd9Sstevel@tonic-gate "en_AU:         ISO_8859-1:1987",
273*7c478bd9Sstevel@tonic-gate "en_CA:         ISO_8859-1:1987",
274*7c478bd9Sstevel@tonic-gate "en_TH:         ISO_8859-1:1987",
275*7c478bd9Sstevel@tonic-gate "en_US:         ISO_8859-1:1987",
276*7c478bd9Sstevel@tonic-gate "es:            ISO_8859-1:1987",
277*7c478bd9Sstevel@tonic-gate "fi:            ISO_8859-1:1987",
278*7c478bd9Sstevel@tonic-gate "fr:            ISO_8859-1:1987",
279*7c478bd9Sstevel@tonic-gate "fr_BE:         ISO_8859-1:1987",
280*7c478bd9Sstevel@tonic-gate "fr_CA:         ISO_8859-1:1987",
281*7c478bd9Sstevel@tonic-gate "fr_CH:         ISO_8859-1:1987",
282*7c478bd9Sstevel@tonic-gate "is:            ISO_8859-1:1987",
283*7c478bd9Sstevel@tonic-gate "it:            ISO_8859-1:1987",
284*7c478bd9Sstevel@tonic-gate "it_CH:         ISO_8859-1:1987",
285*7c478bd9Sstevel@tonic-gate "ja_JP.EUC:     Extended_UNIX_Code_Packed_Format_for_Japanese",
286*7c478bd9Sstevel@tonic-gate "ko_KR.euc:     EUC-KR",
287*7c478bd9Sstevel@tonic-gate "nl:            ISO_8859-1:1987",
288*7c478bd9Sstevel@tonic-gate "nl_BE:         ISO_8859-1:1987",
289*7c478bd9Sstevel@tonic-gate "no:            ISO_8859-1:1987",
290*7c478bd9Sstevel@tonic-gate "pl:            ISO_8859-2:1987",
291*7c478bd9Sstevel@tonic-gate "pt:            ISO_8859-1:1987",
292*7c478bd9Sstevel@tonic-gate "sh:            ISO_8859-2:1987",
293*7c478bd9Sstevel@tonic-gate "sk:            ISO_8859-2:1987",
294*7c478bd9Sstevel@tonic-gate "sv:            ISO_8859-1:1987",
295*7c478bd9Sstevel@tonic-gate "zh_CN.ugb:     GB2312",
296*7c478bd9Sstevel@tonic-gate "zh_TW.ucns:    cns11643_1",
297*7c478bd9Sstevel@tonic-gate NULL
298*7c478bd9Sstevel@tonic-gate };
299*7c478bd9Sstevel@tonic-gate #elif defined(SOLARIS)
300*7c478bd9Sstevel@tonic-gate const char *CHARCONVTABLE[] =
301*7c478bd9Sstevel@tonic-gate {
302*7c478bd9Sstevel@tonic-gate "! This table maps the host's locale names to IANA charsets",
303*7c478bd9Sstevel@tonic-gate "!",
304*7c478bd9Sstevel@tonic-gate "C:             ISO_8859-1:1987",
305*7c478bd9Sstevel@tonic-gate "ja:            Extended_UNIX_Code_Packed_Format_for_Japanese",
306*7c478bd9Sstevel@tonic-gate "ja_JP.EUC:     Extended_UNIX_Code_Packed_Format_for_Japanese",
307*7c478bd9Sstevel@tonic-gate "ja_JP.PCK:     Shift_JIS",
308*7c478bd9Sstevel@tonic-gate "en:		ISO_8859-1:1987",
309*7c478bd9Sstevel@tonic-gate "en_AU:		ISO_8859-1:1987",
310*7c478bd9Sstevel@tonic-gate "en_CA:		ISO_8859-1:1987",
311*7c478bd9Sstevel@tonic-gate "en_UK:		ISO_8859-1:1987",
312*7c478bd9Sstevel@tonic-gate "en_US:		ISO_8859-1:1987",
313*7c478bd9Sstevel@tonic-gate "es:		ISO_8859-1:1987",
314*7c478bd9Sstevel@tonic-gate "es_AR:		ISO_8859-1:1987",
315*7c478bd9Sstevel@tonic-gate "es_BO:		ISO_8859-1:1987",
316*7c478bd9Sstevel@tonic-gate "es_CL:		ISO_8859-1:1987",
317*7c478bd9Sstevel@tonic-gate "es_CO:		ISO_8859-1:1987",
318*7c478bd9Sstevel@tonic-gate "es_CR:		ISO_8859-1:1987",
319*7c478bd9Sstevel@tonic-gate "es_EC:		ISO_8859-1:1987",
320*7c478bd9Sstevel@tonic-gate "es_GT:		ISO_8859-1:1987",
321*7c478bd9Sstevel@tonic-gate "es_MX:		ISO_8859-1:1987",
322*7c478bd9Sstevel@tonic-gate "es_NI:		ISO_8859-1:1987",
323*7c478bd9Sstevel@tonic-gate "es_PA:		ISO_8859-1:1987",
324*7c478bd9Sstevel@tonic-gate "es_PE:		ISO_8859-1:1987",
325*7c478bd9Sstevel@tonic-gate "es_PY:		ISO_8859-1:1987",
326*7c478bd9Sstevel@tonic-gate "es_SV:		ISO_8859-1:1987",
327*7c478bd9Sstevel@tonic-gate "es_UY:		ISO_8859-1:1987",
328*7c478bd9Sstevel@tonic-gate "es_VE:		ISO_8859-1:1987",
329*7c478bd9Sstevel@tonic-gate "fr:		ISO_8859-1:1987",
330*7c478bd9Sstevel@tonic-gate "fr_BE:		ISO_8859-1:1987",
331*7c478bd9Sstevel@tonic-gate "fr_CA:		ISO_8859-1:1987",
332*7c478bd9Sstevel@tonic-gate "fr_CH:		ISO_8859-1:1987",
333*7c478bd9Sstevel@tonic-gate "de:		ISO_8859-1:1987",
334*7c478bd9Sstevel@tonic-gate "de_AT:		ISO_8859-1:1987",
335*7c478bd9Sstevel@tonic-gate "de_CH:		ISO_8859-1:1987",
336*7c478bd9Sstevel@tonic-gate "nl:		ISO_8859-1:1987",
337*7c478bd9Sstevel@tonic-gate "nl_BE:		ISO_8859-1:1987",
338*7c478bd9Sstevel@tonic-gate "it:		ISO_8859-1:1987",
339*7c478bd9Sstevel@tonic-gate "sv:		ISO_8859-1:1987",
340*7c478bd9Sstevel@tonic-gate "no:		ISO_8859-1:1987",
341*7c478bd9Sstevel@tonic-gate "da:		ISO_8859-1:1987",
342*7c478bd9Sstevel@tonic-gate "iso_8859_1:    ISO_8859-1:1987",
343*7c478bd9Sstevel@tonic-gate "japanese:      Extended_UNIX_Code_Packed_Format_for_Japanese",
344*7c478bd9Sstevel@tonic-gate "ko:            EUC-KR",
345*7c478bd9Sstevel@tonic-gate "zh:            GB2312",
346*7c478bd9Sstevel@tonic-gate "zh_TW:         cns11643_1",
347*7c478bd9Sstevel@tonic-gate NULL
348*7c478bd9Sstevel@tonic-gate };
349*7c478bd9Sstevel@tonic-gate #elif defined(OSF1)
350*7c478bd9Sstevel@tonic-gate const char *CHARCONVTABLE[] =
351*7c478bd9Sstevel@tonic-gate {
352*7c478bd9Sstevel@tonic-gate "! This table maps the host's locale names to IANA charsets",
353*7c478bd9Sstevel@tonic-gate "!",
354*7c478bd9Sstevel@tonic-gate "C:                     ISO_8859-1:1987",
355*7c478bd9Sstevel@tonic-gate "cs_CZ.ISO8859-2:       ISO_8859-2:1987",
356*7c478bd9Sstevel@tonic-gate "cs_CZ:                 ISO_8859-2:1987",
357*7c478bd9Sstevel@tonic-gate "da_DK.ISO8859-1:       ISO_8859-1:1987",
358*7c478bd9Sstevel@tonic-gate "de_CH.ISO8859-1:       ISO_8859-1:1987",
359*7c478bd9Sstevel@tonic-gate "de_DE.ISO8859-1:       ISO_8859-1:1987",
360*7c478bd9Sstevel@tonic-gate "en_GB.ISO8859-1:       ISO_8859-1:1987",
361*7c478bd9Sstevel@tonic-gate "en_US.ISO8859-1:       ISO_8859-1:1987",
362*7c478bd9Sstevel@tonic-gate "es_ES.ISO8859-1:       ISO_8859-1:1987",
363*7c478bd9Sstevel@tonic-gate "fi_FI.ISO8859-1:       ISO_8859-1:1987",
364*7c478bd9Sstevel@tonic-gate "fr_BE.ISO8859-1:       ISO_8859-1:1987",
365*7c478bd9Sstevel@tonic-gate "fr_CA.ISO8859-1:       ISO_8859-1:1987",
366*7c478bd9Sstevel@tonic-gate "fr_CH.ISO8859-1:       ISO_8859-1:1987",
367*7c478bd9Sstevel@tonic-gate "fr_FR.ISO8859-1:       ISO_8859-1:1987",
368*7c478bd9Sstevel@tonic-gate "hu_HU.ISO8859-2:       ISO_8859-2:1987",
369*7c478bd9Sstevel@tonic-gate "hu_HU:                 ISO_8859-2:1987",
370*7c478bd9Sstevel@tonic-gate "is_IS.ISO8859-1:       ISO_8859-1:1987",
371*7c478bd9Sstevel@tonic-gate "it_IT.ISO8859-1:       ISO_8859-1:1987",
372*7c478bd9Sstevel@tonic-gate "ja_JP.SJIS:            Shift_JIS",
373*7c478bd9Sstevel@tonic-gate "ja_JP.eucJP:           Extended_UNIX_Code_Packed_Format_for_Japanese",
374*7c478bd9Sstevel@tonic-gate "ja_JP:                 Extended_UNIX_Code_Packed_Format_for_Japanese",
375*7c478bd9Sstevel@tonic-gate "ko_KR.eucKR:           EUC-KR",
376*7c478bd9Sstevel@tonic-gate "ko_KR:                 EUC-KR",
377*7c478bd9Sstevel@tonic-gate "nl_BE.ISO8859-1:       ISO_8859-1:1987",
378*7c478bd9Sstevel@tonic-gate "nl_NL.ISO8859-1:       ISO_8859-1:1987",
379*7c478bd9Sstevel@tonic-gate "no_NO.ISO8859-1:       ISO_8859-1:1987",
380*7c478bd9Sstevel@tonic-gate "pl_PL.ISO8859-2:       ISO_8859-2:1987",
381*7c478bd9Sstevel@tonic-gate "pl_PL:                 ISO_8859-2:1987",
382*7c478bd9Sstevel@tonic-gate "pt_PT.ISO8859-1:       ISO_8859-1:1987",
383*7c478bd9Sstevel@tonic-gate "sk_SK.ISO8859-2:       ISO_8859-2:1987",
384*7c478bd9Sstevel@tonic-gate "sk_SK:                 ISO_8859-2:1987",
385*7c478bd9Sstevel@tonic-gate "sv_SE.ISO8859-1:       ISO_8859-1:1987",
386*7c478bd9Sstevel@tonic-gate "zh_CN:                 GB2312",
387*7c478bd9Sstevel@tonic-gate "zh_HK.big5:            Big5",
388*7c478bd9Sstevel@tonic-gate "zh_HK.eucTW:           cns11643_1",
389*7c478bd9Sstevel@tonic-gate "zh_TW.big5:            Big5",
390*7c478bd9Sstevel@tonic-gate "zh_TW.big5@chuyin:     Big5",
391*7c478bd9Sstevel@tonic-gate "zh_TW.big5@radical:    Big5",
392*7c478bd9Sstevel@tonic-gate "zh_TW.big5@stroke:     Big5",
393*7c478bd9Sstevel@tonic-gate "zh_TW.eucTW:           cns11643_1",
394*7c478bd9Sstevel@tonic-gate "zh_TW.eucTW@chuyin:    cns11643_1",
395*7c478bd9Sstevel@tonic-gate "zh_TW.eucTW@radical:   cns11643_1",
396*7c478bd9Sstevel@tonic-gate "zh_TW.eucTW@stroke:    cns11643_1",
397*7c478bd9Sstevel@tonic-gate "zh_TW:                 cns11643_1",
398*7c478bd9Sstevel@tonic-gate NULL
399*7c478bd9Sstevel@tonic-gate };
400*7c478bd9Sstevel@tonic-gate #elif defined(HPUX)
401*7c478bd9Sstevel@tonic-gate const char *CHARCONVTABLE[] =
402*7c478bd9Sstevel@tonic-gate {
403*7c478bd9Sstevel@tonic-gate "! This table maps the host's locale names to IANA charsets",
404*7c478bd9Sstevel@tonic-gate "!",
405*7c478bd9Sstevel@tonic-gate "C:			ISO_8859-1:1987",
406*7c478bd9Sstevel@tonic-gate "ja_JP:			Extended_UNIX_Code_Packed_Format_for_Japanese",
407*7c478bd9Sstevel@tonic-gate "ja_JP.SJIS:		Shift_JIS",
408*7c478bd9Sstevel@tonic-gate "ja_JP.eucJP:		Extended_UNIX_Code_Packed_Format_for_Japanese",
409*7c478bd9Sstevel@tonic-gate "es_ES:			ISO_8859-1:1987",
410*7c478bd9Sstevel@tonic-gate "es_ES.iso88591:	ISO_8859-1:1987",
411*7c478bd9Sstevel@tonic-gate "sv_SE:			ISO_8859-1:1987",
412*7c478bd9Sstevel@tonic-gate "sv_SE.iso88591:	ISO_8859-1:1987",
413*7c478bd9Sstevel@tonic-gate "da_DK:			ISO_8859-1:1987",
414*7c478bd9Sstevel@tonic-gate "da_DK.iso88591:	ISO_8859-1:1987",
415*7c478bd9Sstevel@tonic-gate "nl_NL:			ISO_8859-1:1987",
416*7c478bd9Sstevel@tonic-gate "nl_NL.iso88591:	ISO_8859-1:1987",
417*7c478bd9Sstevel@tonic-gate "en:			ISO_8859-1:1987",
418*7c478bd9Sstevel@tonic-gate "en_GB:			ISO_8859-1:1987",
419*7c478bd9Sstevel@tonic-gate "en_GB.iso88591:	ISO_8859-1:1987",
420*7c478bd9Sstevel@tonic-gate "en_US:			ISO_8859-1:1987",
421*7c478bd9Sstevel@tonic-gate "en_US.iso88591:	ISO_8859-1:1987",
422*7c478bd9Sstevel@tonic-gate "fi_FI:			ISO_8859-1:1987",
423*7c478bd9Sstevel@tonic-gate "fi_FI.iso88591:	ISO_8859-1:1987",
424*7c478bd9Sstevel@tonic-gate "fr_CA:			ISO_8859-1:1987",
425*7c478bd9Sstevel@tonic-gate "fr_CA.iso88591:	ISO_8859-1:1987",
426*7c478bd9Sstevel@tonic-gate "fr_FR:			ISO_8859-1:1987",
427*7c478bd9Sstevel@tonic-gate "fr_FR.iso88591:	ISO_8859-1:1987",
428*7c478bd9Sstevel@tonic-gate "de_DE:			ISO_8859-1:1987",
429*7c478bd9Sstevel@tonic-gate "de_DE.iso88591:	ISO_8859-1:1987",
430*7c478bd9Sstevel@tonic-gate "is_IS:			ISO_8859-1:1987",
431*7c478bd9Sstevel@tonic-gate "is_IS.iso88591:	ISO_8859-1:1987",
432*7c478bd9Sstevel@tonic-gate "it_IT:			ISO_8859-1:1987",
433*7c478bd9Sstevel@tonic-gate "it_IT.iso88591:	ISO_8859-1:1987",
434*7c478bd9Sstevel@tonic-gate "no_NO:			ISO_8859-1:1987",
435*7c478bd9Sstevel@tonic-gate "no_NO.iso88591:	ISO_8859-1:1987",
436*7c478bd9Sstevel@tonic-gate "pt_PT:			ISO_8859-1:1987",
437*7c478bd9Sstevel@tonic-gate "pt_PT.iso88591:	ISO_8859-1:1987",
438*7c478bd9Sstevel@tonic-gate "hu_HU:			ISO_8859-2:1987",
439*7c478bd9Sstevel@tonic-gate "hu_HU.iso88592:	ISO_8859-2:1987",
440*7c478bd9Sstevel@tonic-gate "cs_CZ:			ISO_8859-2:1987",
441*7c478bd9Sstevel@tonic-gate "cs_CZ.iso88592:	ISO_8859-2:1987",
442*7c478bd9Sstevel@tonic-gate "pl_PL:			ISO_8859-2:1987",
443*7c478bd9Sstevel@tonic-gate "pl_PL.iso88592:	ISO_8859-2:1987",
444*7c478bd9Sstevel@tonic-gate "ro_RO:			ISO_8859-2:1987",
445*7c478bd9Sstevel@tonic-gate "ro_RO.iso88592:	ISO_8859-2:1987",
446*7c478bd9Sstevel@tonic-gate "hr_HR:			ISO_8859-2:1987",
447*7c478bd9Sstevel@tonic-gate "hr_HR.iso88592:	ISO_8859-2:1987",
448*7c478bd9Sstevel@tonic-gate "sk_SK:			ISO_8859-2:1987",
449*7c478bd9Sstevel@tonic-gate "sk_SK.iso88592:	ISO_8859-2:1987",
450*7c478bd9Sstevel@tonic-gate "sl_SI:			ISO_8859-2:1987",
451*7c478bd9Sstevel@tonic-gate "sl_SI.iso88592:	ISO_8859-2:1987",
452*7c478bd9Sstevel@tonic-gate "american.iso88591:     ISO_8859-1:1987",
453*7c478bd9Sstevel@tonic-gate "bulgarian:             ISO_8859-2:1987",
454*7c478bd9Sstevel@tonic-gate "c-french.iso88591:     ISO_8859-1:1987",
455*7c478bd9Sstevel@tonic-gate "chinese-s:             GB2312",
456*7c478bd9Sstevel@tonic-gate "chinese-t.big5:                Big5",
457*7c478bd9Sstevel@tonic-gate "czech:                 ISO_8859-2:1987",
458*7c478bd9Sstevel@tonic-gate "danish.iso88591:       ISO_8859-1:1987",
459*7c478bd9Sstevel@tonic-gate "dutch.iso88591:                ISO_8859-1:1987",
460*7c478bd9Sstevel@tonic-gate "english.iso88591:      ISO_8859-1:1987",
461*7c478bd9Sstevel@tonic-gate "finnish.iso88591:      ISO_8859-1:1987",
462*7c478bd9Sstevel@tonic-gate "french.iso88591:       ISO_8859-1:1987",
463*7c478bd9Sstevel@tonic-gate "german.iso88591:       ISO_8859-1:1987",
464*7c478bd9Sstevel@tonic-gate "hungarian:             ISO_8859-2:1987",
465*7c478bd9Sstevel@tonic-gate "icelandic.iso88591:    ISO_8859-1:1987",
466*7c478bd9Sstevel@tonic-gate "italian.iso88591:      ISO_8859-1:1987",
467*7c478bd9Sstevel@tonic-gate "japanese.euc:          Extended_UNIX_Code_Packed_Format_for_Japanese",
468*7c478bd9Sstevel@tonic-gate "japanese:              Shift_JIS",
469*7c478bd9Sstevel@tonic-gate "katakana:              Shift_JIS",
470*7c478bd9Sstevel@tonic-gate "korean:                        EUC-KR",
471*7c478bd9Sstevel@tonic-gate "norwegian.iso88591:    ISO_8859-1:1987",
472*7c478bd9Sstevel@tonic-gate "polish:                        ISO_8859-2:1987",
473*7c478bd9Sstevel@tonic-gate "portuguese.iso88591:   ISO_8859-1:1987",
474*7c478bd9Sstevel@tonic-gate "rumanian:              ISO_8859-2:1987",
475*7c478bd9Sstevel@tonic-gate "serbocroatian:         ISO_8859-2:1987",
476*7c478bd9Sstevel@tonic-gate "slovene:               ISO_8859-2:1987",
477*7c478bd9Sstevel@tonic-gate "spanish.iso88591:      ISO_8859-1:1987",
478*7c478bd9Sstevel@tonic-gate "swedish.iso88591:      ISO_8859-1:1987",
479*7c478bd9Sstevel@tonic-gate NULL
480*7c478bd9Sstevel@tonic-gate };
481*7c478bd9Sstevel@tonic-gate #elif defined(AIX)
482*7c478bd9Sstevel@tonic-gate const char *CHARCONVTABLE[] =
483*7c478bd9Sstevel@tonic-gate {
484*7c478bd9Sstevel@tonic-gate "! This table maps the host's locale names to IANA charsets",
485*7c478bd9Sstevel@tonic-gate "!",
486*7c478bd9Sstevel@tonic-gate "C:                     ISO_8859-1:1987",
487*7c478bd9Sstevel@tonic-gate "En_JP.IBM-932:         Shift_JIS",
488*7c478bd9Sstevel@tonic-gate "En_JP:                 Shift_JIS",
489*7c478bd9Sstevel@tonic-gate "Ja_JP.IBM-932:         Shift_JIS",
490*7c478bd9Sstevel@tonic-gate "Ja_JP:                 Shift_JIS",
491*7c478bd9Sstevel@tonic-gate "da_DK.ISO8859-1:       ISO_8859-1:1987",
492*7c478bd9Sstevel@tonic-gate "da_DK:                 ISO_8859-1:1987",
493*7c478bd9Sstevel@tonic-gate "de_CH.ISO8859-1:       ISO_8859-1:1987",
494*7c478bd9Sstevel@tonic-gate "de_CH:                 ISO_8859-1:1987",
495*7c478bd9Sstevel@tonic-gate "de_DE.ISO8859-1:       ISO_8859-1:1987",
496*7c478bd9Sstevel@tonic-gate "de_DE:                 ISO_8859-1:1987",
497*7c478bd9Sstevel@tonic-gate "en_GB.ISO8859-1:       ISO_8859-1:1987",
498*7c478bd9Sstevel@tonic-gate "en_GB:                 ISO_8859-1:1987",
499*7c478bd9Sstevel@tonic-gate "en_JP.IBM-eucJP:       Extended_UNIX_Code_Packed_Format_for_Japanese",
500*7c478bd9Sstevel@tonic-gate "en_JP:                 Extended_UNIX_Code_Packed_Format_for_Japanese",
501*7c478bd9Sstevel@tonic-gate "en_KR.IBM-eucKR:       EUC-KR",
502*7c478bd9Sstevel@tonic-gate "en_KR:                 EUC-KR",
503*7c478bd9Sstevel@tonic-gate "en_TW.IBM-eucTW:       cns11643_1",
504*7c478bd9Sstevel@tonic-gate "en_TW:                 cns11643_1",
505*7c478bd9Sstevel@tonic-gate "en_US.ISO8859-1:       ISO_8859-1:1987",
506*7c478bd9Sstevel@tonic-gate "en_US:                 ISO_8859-1:1987",
507*7c478bd9Sstevel@tonic-gate "es_ES.ISO8859-1:       ISO_8859-1:1987",
508*7c478bd9Sstevel@tonic-gate "es_ES:                 ISO_8859-1:1987",
509*7c478bd9Sstevel@tonic-gate "fi_FI.ISO8859-1:       ISO_8859-1:1987",
510*7c478bd9Sstevel@tonic-gate "fi_FI:                 ISO_8859-1:1987",
511*7c478bd9Sstevel@tonic-gate "fr_BE.ISO8859-1:       ISO_8859-1:1987",
512*7c478bd9Sstevel@tonic-gate "fr_BE:                 ISO_8859-1:1987",
513*7c478bd9Sstevel@tonic-gate "fr_CA.ISO8859-1:       ISO_8859-1:1987",
514*7c478bd9Sstevel@tonic-gate "fr_CA:                 ISO_8859-1:1987",
515*7c478bd9Sstevel@tonic-gate "fr_CH.ISO8859-1:       ISO_8859-1:1987",
516*7c478bd9Sstevel@tonic-gate "fr_CH:                 ISO_8859-1:1987",
517*7c478bd9Sstevel@tonic-gate "fr_FR.ISO8859-1:       ISO_8859-1:1987",
518*7c478bd9Sstevel@tonic-gate "fr_FR:                 ISO_8859-1:1987",
519*7c478bd9Sstevel@tonic-gate "is_IS.ISO8859-1:       ISO_8859-1:1987",
520*7c478bd9Sstevel@tonic-gate "is_IS:                 ISO_8859-1:1987",
521*7c478bd9Sstevel@tonic-gate "it_IT.ISO8859-1:       ISO_8859-1:1987",
522*7c478bd9Sstevel@tonic-gate "it_IT:                 ISO_8859-1:1987",
523*7c478bd9Sstevel@tonic-gate "ja_JP.IBM-eucJP:       Extended_UNIX_Code_Packed_Format_for_Japanese",
524*7c478bd9Sstevel@tonic-gate "ja_JP:                 Extended_UNIX_Code_Packed_Format_for_Japanese",
525*7c478bd9Sstevel@tonic-gate "ko_KR.IBM-eucKR:       EUC-KR",
526*7c478bd9Sstevel@tonic-gate "ko_KR:                 EUC-KR",
527*7c478bd9Sstevel@tonic-gate "nl_BE.ISO8859-1:       ISO_8859-1:1987",
528*7c478bd9Sstevel@tonic-gate "nl_BE:                 ISO_8859-1:1987",
529*7c478bd9Sstevel@tonic-gate "nl_NL.ISO8859-1:       ISO_8859-1:1987",
530*7c478bd9Sstevel@tonic-gate "nl_NL:                 ISO_8859-1:1987",
531*7c478bd9Sstevel@tonic-gate "no_NO.ISO8859-1:       ISO_8859-1:1987",
532*7c478bd9Sstevel@tonic-gate "no_NO:                 ISO_8859-1:1987",
533*7c478bd9Sstevel@tonic-gate "pt_PT.ISO8859-1:       ISO_8859-1:1987",
534*7c478bd9Sstevel@tonic-gate "pt_PT:                 ISO_8859-1:1987",
535*7c478bd9Sstevel@tonic-gate "sv_SE.ISO8859-1:       ISO_8859-1:1987",
536*7c478bd9Sstevel@tonic-gate "sv_SE:                 ISO_8859-1:1987",
537*7c478bd9Sstevel@tonic-gate "zh_TW.IBM-eucTW:       cns11643_1",
538*7c478bd9Sstevel@tonic-gate "zh_TW:                 cns11643_1",
539*7c478bd9Sstevel@tonic-gate NULL
540*7c478bd9Sstevel@tonic-gate };
541*7c478bd9Sstevel@tonic-gate #else   // sunos by default
542*7c478bd9Sstevel@tonic-gate const char *CHARCONVTABLE[] =
543*7c478bd9Sstevel@tonic-gate {
544*7c478bd9Sstevel@tonic-gate "! This table maps the host's locale names to IANA charsets",
545*7c478bd9Sstevel@tonic-gate "!",
546*7c478bd9Sstevel@tonic-gate "C:             ISO_8859-1:1987",
547*7c478bd9Sstevel@tonic-gate "de:            ISO_8859-1:1987",
548*7c478bd9Sstevel@tonic-gate "en_US:         ISO_8859-1:1987",
549*7c478bd9Sstevel@tonic-gate "es:            ISO_8859-1:1987",
550*7c478bd9Sstevel@tonic-gate "fr:            ISO_8859-1:1987",
551*7c478bd9Sstevel@tonic-gate "iso_8859_1:    ISO_8859-1:1987",
552*7c478bd9Sstevel@tonic-gate "it:            ISO_8859-1:1987",
553*7c478bd9Sstevel@tonic-gate "ja:            Extended_UNIX_Code_Packed_Format_for_Japanese",
554*7c478bd9Sstevel@tonic-gate "ja_JP.EUC:     Extended_UNIX_Code_Packed_Format_for_Japanese",
555*7c478bd9Sstevel@tonic-gate "japanese:      Extended_UNIX_Code_Packed_Format_for_Japanese",
556*7c478bd9Sstevel@tonic-gate "ko:            EUC-KR",
557*7c478bd9Sstevel@tonic-gate "sv:            ISO_8859-1:1987",
558*7c478bd9Sstevel@tonic-gate "zh:            GB2312",
559*7c478bd9Sstevel@tonic-gate "zh_TW:         cns11643_1",
560*7c478bd9Sstevel@tonic-gate NULL
561*7c478bd9Sstevel@tonic-gate };
562*7c478bd9Sstevel@tonic-gate #endif
563*7c478bd9Sstevel@tonic-gate 
564*7c478bd9Sstevel@tonic-gate #define BSZ     256
565*7c478bd9Sstevel@tonic-gate 
566*7c478bd9Sstevel@tonic-gate char *
567*7c478bd9Sstevel@tonic-gate GetCharsetFromLocale(char *locale)
568*7c478bd9Sstevel@tonic-gate {
569*7c478bd9Sstevel@tonic-gate     char *tmpcharset = NULL;
570*7c478bd9Sstevel@tonic-gate     char buf[BSZ];
571*7c478bd9Sstevel@tonic-gate     char *p;
572*7c478bd9Sstevel@tonic-gate     const char *line;
573*7c478bd9Sstevel@tonic-gate     int i=0;
574*7c478bd9Sstevel@tonic-gate 
575*7c478bd9Sstevel@tonic-gate     line = CHARCONVTABLE[i];
576*7c478bd9Sstevel@tonic-gate     while (line != NULL)
577*7c478bd9Sstevel@tonic-gate     {
578*7c478bd9Sstevel@tonic-gate        if (*line == 0)
579*7c478bd9Sstevel@tonic-gate        {
580*7c478bd9Sstevel@tonic-gate           break;
581*7c478bd9Sstevel@tonic-gate        }
582*7c478bd9Sstevel@tonic-gate 
583*7c478bd9Sstevel@tonic-gate        strcpy(buf, line);
584*7c478bd9Sstevel@tonic-gate        line = CHARCONVTABLE[++i];
585*7c478bd9Sstevel@tonic-gate 
586*7c478bd9Sstevel@tonic-gate        if (strlen(buf) == 0 || buf[0] == '!')
587*7c478bd9Sstevel@tonic-gate        {
588*7c478bd9Sstevel@tonic-gate           continue;
589*7c478bd9Sstevel@tonic-gate        }
590*7c478bd9Sstevel@tonic-gate        p = strchr(buf, ':');
591*7c478bd9Sstevel@tonic-gate        if (p == NULL)
592*7c478bd9Sstevel@tonic-gate        {
593*7c478bd9Sstevel@tonic-gate           tmpcharset = NULL;
594*7c478bd9Sstevel@tonic-gate           break;
595*7c478bd9Sstevel@tonic-gate        }
596*7c478bd9Sstevel@tonic-gate        *p = 0;
597*7c478bd9Sstevel@tonic-gate        if (strcmp(buf, locale) == 0) {
598*7c478bd9Sstevel@tonic-gate           while (*++p == ' ' || *p == '\t')
599*7c478bd9Sstevel@tonic-gate              ;
600*7c478bd9Sstevel@tonic-gate           if (isalpha(*p)) {
601*7c478bd9Sstevel@tonic-gate              tmpcharset = strdup(p);
602*7c478bd9Sstevel@tonic-gate           } else
603*7c478bd9Sstevel@tonic-gate              tmpcharset = NULL;
604*7c478bd9Sstevel@tonic-gate 
605*7c478bd9Sstevel@tonic-gate           break;
606*7c478bd9Sstevel@tonic-gate        }
607*7c478bd9Sstevel@tonic-gate     }
608*7c478bd9Sstevel@tonic-gate     return tmpcharset;
609*7c478bd9Sstevel@tonic-gate }
610*7c478bd9Sstevel@tonic-gate 
611*7c478bd9Sstevel@tonic-gate #endif /* Not defined XP_WIN32 */
612*7c478bd9Sstevel@tonic-gate 
613*7c478bd9Sstevel@tonic-gate #ifdef XP_WIN32
614*7c478bd9Sstevel@tonic-gate char *_convertor(const char *instr, int bFromUTF8)
615*7c478bd9Sstevel@tonic-gate {
616*7c478bd9Sstevel@tonic-gate     char  *outstr = NULL;
617*7c478bd9Sstevel@tonic-gate     int    inlen, wclen, outlen;
618*7c478bd9Sstevel@tonic-gate     LPWSTR wcstr;
619*7c478bd9Sstevel@tonic-gate 
620*7c478bd9Sstevel@tonic-gate     if (instr == NULL)
621*7c478bd9Sstevel@tonic-gate             return NULL;
622*7c478bd9Sstevel@tonic-gate 
623*7c478bd9Sstevel@tonic-gate     if ((inlen = strlen(instr)) <= 0)
624*7c478bd9Sstevel@tonic-gate             return NULL;
625*7c478bd9Sstevel@tonic-gate 
626*7c478bd9Sstevel@tonic-gate     /* output never becomes longer than input,
627*7c478bd9Sstevel@tonic-gate      * thus we don't have to ask for the length
628*7c478bd9Sstevel@tonic-gate      */
629*7c478bd9Sstevel@tonic-gate     wcstr = (LPWSTR) malloc( sizeof( WCHAR ) * (inlen+1) );
630*7c478bd9Sstevel@tonic-gate     if (!wcstr)
631*7c478bd9Sstevel@tonic-gate         return NULL;
632*7c478bd9Sstevel@tonic-gate 
633*7c478bd9Sstevel@tonic-gate     wclen = MultiByteToWideChar(bFromUTF8 ? CP_UTF8 : CP_ACP, 0, instr,
634*7c478bd9Sstevel@tonic-gate                                  inlen, wcstr, inlen);
635*7c478bd9Sstevel@tonic-gate     outlen = WideCharToMultiByte(bFromUTF8 ? CP_ACP : CP_UTF8, 0, wcstr,
636*7c478bd9Sstevel@tonic-gate                                   wclen, NULL, 0, NULL, NULL);
637*7c478bd9Sstevel@tonic-gate 
638*7c478bd9Sstevel@tonic-gate     if (outlen > 0) {
639*7c478bd9Sstevel@tonic-gate         outstr = (char *) malloc(outlen + 2);
640*7c478bd9Sstevel@tonic-gate         outlen = WideCharToMultiByte(bFromUTF8 ? CP_ACP : CP_UTF8, 0, wcstr,
641*7c478bd9Sstevel@tonic-gate                                       wclen, outstr, outlen, NULL, NULL);
642*7c478bd9Sstevel@tonic-gate         if (outlen > 0)
643*7c478bd9Sstevel@tonic-gate             *(outstr+outlen) = _T('\0');
644*7c478bd9Sstevel@tonic-gate         else
645*7c478bd9Sstevel@tonic-gate             return NULL;
646*7c478bd9Sstevel@tonic-gate     }
647*7c478bd9Sstevel@tonic-gate     free( wcstr );
648*7c478bd9Sstevel@tonic-gate     return outstr;
649*7c478bd9Sstevel@tonic-gate }
650*7c478bd9Sstevel@tonic-gate #endif
651*7c478bd9Sstevel@tonic-gate 
652*7c478bd9Sstevel@tonic-gate char *
653*7c478bd9Sstevel@tonic-gate ldaptool_local2UTF8( const char *src )
654*7c478bd9Sstevel@tonic-gate {
655*7c478bd9Sstevel@tonic-gate     char *utf8;
656*7c478bd9Sstevel@tonic-gate #ifndef XP_WIN32
657*7c478bd9Sstevel@tonic-gate     char *locale, *newcharset;
658*7c478bd9Sstevel@tonic-gate     size_t outLen, resultLen;
659*7c478bd9Sstevel@tonic-gate     UErrorCode err = U_ZERO_ERROR;
660*7c478bd9Sstevel@tonic-gate     UConverter *cnv;
661*7c478bd9Sstevel@tonic-gate 
662*7c478bd9Sstevel@tonic-gate     if (src == NULL)
663*7c478bd9Sstevel@tonic-gate     {
664*7c478bd9Sstevel@tonic-gate       return NULL;
665*7c478bd9Sstevel@tonic-gate     }
666*7c478bd9Sstevel@tonic-gate     else if (*src == 0 || (ldaptool_charset == NULL)
667*7c478bd9Sstevel@tonic-gate 	     || (!strcmp( ldaptool_charset, "" )))
668*7c478bd9Sstevel@tonic-gate     {
669*7c478bd9Sstevel@tonic-gate 	/* no option specified, so assume it's already in utf-8 */
670*7c478bd9Sstevel@tonic-gate         utf8 = strdup(src);
671*7c478bd9Sstevel@tonic-gate         return utf8;
672*7c478bd9Sstevel@tonic-gate     }
673*7c478bd9Sstevel@tonic-gate 
674*7c478bd9Sstevel@tonic-gate     if( !strcmp( ldaptool_charset, "0" )
675*7c478bd9Sstevel@tonic-gate 	    && (!charsetset) )
676*7c478bd9Sstevel@tonic-gate     {
677*7c478bd9Sstevel@tonic-gate 	/* zero option specified, so try to get default codepage
678*7c478bd9Sstevel@tonic-gate 	   this sucker is strdup'd immediately so it's OK to cast */
679*7c478bd9Sstevel@tonic-gate 	newcharset = (char *)ucnv_getDefaultName();
680*7c478bd9Sstevel@tonic-gate 	if (newcharset != NULL) {
681*7c478bd9Sstevel@tonic-gate 	    free( ldaptool_charset );
682*7c478bd9Sstevel@tonic-gate 	    /* the default codepage lives in ICU */
683*7c478bd9Sstevel@tonic-gate 	    ldaptool_charset = strdup(newcharset);
684*7c478bd9Sstevel@tonic-gate 	    if (ldaptool_charset == NULL) {
685*7c478bd9Sstevel@tonic-gate 		return strdup(src);
686*7c478bd9Sstevel@tonic-gate 	    }
687*7c478bd9Sstevel@tonic-gate 	}
688*7c478bd9Sstevel@tonic-gate 	charsetset = 1;
689*7c478bd9Sstevel@tonic-gate     }
690*7c478bd9Sstevel@tonic-gate     else
691*7c478bd9Sstevel@tonic-gate     if( strcmp( ldaptool_charset, "" ) && (!charsetset) )
692*7c478bd9Sstevel@tonic-gate     {
693*7c478bd9Sstevel@tonic-gate 	/* -i option specified with charset name */
694*7c478bd9Sstevel@tonic-gate         charsetset = 1;
695*7c478bd9Sstevel@tonic-gate     }
696*7c478bd9Sstevel@tonic-gate 
697*7c478bd9Sstevel@tonic-gate     /* do the preflight - get the size needed for the target buffer */
698*7c478bd9Sstevel@tonic-gate     outLen = (size_t) ucnv_convert( "utf-8", ldaptool_charset, NULL, 0, src,
699*7c478bd9Sstevel@tonic-gate                                       strlen( src ) * sizeof(char), &err);
700*7c478bd9Sstevel@tonic-gate 
701*7c478bd9Sstevel@tonic-gate     if ((err != U_BUFFER_OVERFLOW_ERROR) || (outLen == 0)) {
702*7c478bd9Sstevel@tonic-gate       /* default to just a copy of the string - this covers
703*7c478bd9Sstevel@tonic-gate          the case of an illegal charset also */
704*7c478bd9Sstevel@tonic-gate       return strdup(src);
705*7c478bd9Sstevel@tonic-gate     }
706*7c478bd9Sstevel@tonic-gate 
707*7c478bd9Sstevel@tonic-gate     utf8 =  (char *) malloc( outLen + 1);
708*7c478bd9Sstevel@tonic-gate     if( utf8 == NULL ) {
709*7c478bd9Sstevel@tonic-gate       /* if we're already out of memory, does strdup just return NULL? */
710*7c478bd9Sstevel@tonic-gate        return strdup(src);
711*7c478bd9Sstevel@tonic-gate     }
712*7c478bd9Sstevel@tonic-gate 
713*7c478bd9Sstevel@tonic-gate     /* do the actual conversion this time */
714*7c478bd9Sstevel@tonic-gate     err = U_ZERO_ERROR;
715*7c478bd9Sstevel@tonic-gate     resultLen = ucnv_convert( "utf-8", ldaptool_charset, utf8, (outLen + 1), src,
716*7c478bd9Sstevel@tonic-gate 		       strlen(src) * sizeof(char), &err );
717*7c478bd9Sstevel@tonic-gate 
718*7c478bd9Sstevel@tonic-gate     if (!U_SUCCESS(err)) {
719*7c478bd9Sstevel@tonic-gate       free(utf8);
720*7c478bd9Sstevel@tonic-gate       return strdup(src);
721*7c478bd9Sstevel@tonic-gate     }
722*7c478bd9Sstevel@tonic-gate 
723*7c478bd9Sstevel@tonic-gate #else
724*7c478bd9Sstevel@tonic-gate     utf8 = _convertor(src, FALSE);
725*7c478bd9Sstevel@tonic-gate     if( utf8 == NULL )
726*7c478bd9Sstevel@tonic-gate         utf8 = strdup(src);
727*7c478bd9Sstevel@tonic-gate #endif
728*7c478bd9Sstevel@tonic-gate 
729*7c478bd9Sstevel@tonic-gate     return utf8;
730*7c478bd9Sstevel@tonic-gate }
731*7c478bd9Sstevel@tonic-gate #endif /* HAVE_LIBICU */
732*7c478bd9Sstevel@tonic-gate 
733*7c478bd9Sstevel@tonic-gate #ifndef HAVE_LIBICU
734*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus
735*7c478bd9Sstevel@tonic-gate }
736*7c478bd9Sstevel@tonic-gate #endif
737*7c478bd9Sstevel@tonic-gate #endif
738