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