示例#1
0
文件: charcnv.c 项目: AllardJ/Tomato
/**
 * Initialize iconv conversion descriptors.
 *
 * This is called the first time it is needed, and also called again
 * every time the configuration is reloaded, because the charset or
 * codepage might have changed.
 **/
void init_iconv(void)
{
	int c1, c2;
	BOOL did_reload = False;

	/* so that charset_name() works we need to get the UNIX<->UCS2 going
	   first */
	if (!conv_handles[CH_UNIX][CH_UTF16LE])
		conv_handles[CH_UNIX][CH_UTF16LE] = smb_iconv_open(charset_name(CH_UTF16LE), "ASCII");

	if (!conv_handles[CH_UTF16LE][CH_UNIX])
		conv_handles[CH_UTF16LE][CH_UNIX] = smb_iconv_open("ASCII", charset_name(CH_UTF16LE));

	for (c1=0;c1<NUM_CHARSETS;c1++) {
		for (c2=0;c2<NUM_CHARSETS;c2++) {
			const char *n1 = charset_name((charset_t)c1);
			const char *n2 = charset_name((charset_t)c2);
			if (conv_handles[c1][c2] &&
			    strcmp(n1, conv_handles[c1][c2]->from_name) == 0 &&
			    strcmp(n2, conv_handles[c1][c2]->to_name) == 0)
				continue;

			did_reload = True;

			if (conv_handles[c1][c2])
				smb_iconv_close(conv_handles[c1][c2]);

			conv_handles[c1][c2] = smb_iconv_open(n2,n1);
			if (conv_handles[c1][c2] == (smb_iconv_t)-1) {
				DEBUG(0,("init_iconv: Conversion from %s to %s not supported\n",
					 charset_name((charset_t)c1), charset_name((charset_t)c2)));
				if (c1 != CH_UTF16LE && c1 != CH_UTF16BE) {
					n1 = "ASCII";
				}
				if (c2 != CH_UTF16LE && c2 != CH_UTF16BE) {
					n2 = "ASCII";
				}
				DEBUG(0,("init_iconv: Attempting to replace with conversion from %s to %s\n",
					n1, n2 ));
				conv_handles[c1][c2] = smb_iconv_open(n2,n1);
				if (!conv_handles[c1][c2]) {
					DEBUG(0,("init_iconv: Conversion from %s to %s failed", n1, n2));
					smb_panic("init_iconv: conv_handle initialization failed.");
				}
			}
		}
	}

	if (did_reload) {
		/* XXX: Does this really get called every time the dos
		 * codepage changes? */
		/* XXX: Is the did_reload test too strict? */
		conv_silent = True;
		init_doschar_table();
		init_valid_table();
		conv_silent = False;
	}
}
示例#2
0
文件: charcnv.c 项目: AllardJ/Tomato
/**
 * Destroy global objects allocated by init_iconv()
 **/
void gfree_charcnv(void)
{
	int c1, c2;

	for (c1=0;c1<NUM_CHARSETS;c1++) {
		for (c2=0;c2<NUM_CHARSETS;c2++) {
			if ( conv_handles[c1][c2] ) {
				smb_iconv_close( conv_handles[c1][c2] );
				conv_handles[c1][c2] = 0;
			}
		}
	}
}
示例#3
0
bool set_iconv(smb_iconv_t* t, const char* to, const char* from)
{
	smb_iconv_t cd = (smb_iconv_t)-1;

	if (to && from) {
		to   = get_charset(to);
		from = get_charset(from);
		cd   = smb_iconv_open(to, from);
		if (cd == ((smb_iconv_t)-1)) {
			return false;
		}
	}
	if ((*t != (smb_iconv_t)NULL) && (*t != (smb_iconv_t)-1)) {
		smb_iconv_close(*t);
	}
	*t = cd;
	return true;
}
示例#4
0
文件: charcnv.c 项目: AllardJ/Tomato
/**
 * Return the name of a charset to give to iconv().
 **/
static const char *charset_name(charset_t ch)
{
	const char *ret = NULL;

	if (ch == CH_UTF16LE) ret = "UTF-16LE";
	else if (ch == CH_UTF16BE) ret = "UTF-16BE";
	else if (ch == CH_UNIX) ret = lp_unix_charset();
	else if (ch == CH_DOS) ret = lp_dos_charset();
	else if (ch == CH_DISPLAY) ret = lp_display_charset();
	else if (ch == CH_UTF8) ret = "UTF8";

#if defined(HAVE_NL_LANGINFO) && defined(CODESET)
	if (ret && !strcmp(ret, "LOCALE")) {
		const char *ln = NULL;

#ifdef HAVE_SETLOCALE
		setlocale(LC_ALL, "");
#endif
		ln = nl_langinfo(CODESET);
		if (ln) {
			/* Check whether the charset name is supported
			   by iconv */
			smb_iconv_t handle = smb_iconv_open(ln,"UCS-2LE");
			if (handle == (smb_iconv_t) -1) {
				DEBUG(5,("Locale charset '%s' unsupported, using ASCII instead\n", ln));
				ln = NULL;
			} else {
				DEBUG(5,("Substituting charset '%s' for LOCALE\n", ln));
				smb_iconv_close(handle);
			}
		}
		ret = ln;
	}
#endif

	if (!ret || !*ret) ret = "ASCII";
	return ret;
}