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