Beispiel #1
0
/**
 * 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;
	}
}
Beispiel #2
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;
}
Beispiel #3
0
/**
 * 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;
}
Beispiel #4
0
int main(int argc, char *argv[])
{
	const char *file = NULL;
	char *from = "";
	char *to = "";
	char *output = NULL;
	const char *preload_modules[] = {NULL, NULL};
	FILE *out = stdout;
	int fd;
	smb_iconv_t cd;

	/* make sure the vars that get altered (4th field) are in
	   a fixed location or certain compilers complain */
	poptContext pc;
	struct poptOption long_options[] = {
		POPT_AUTOHELP
		{ "from-code", 'f', POPT_ARG_STRING, &from, 0, "Encoding of original text" },
		{ "to-code", 't', POPT_ARG_STRING, &to, 0, "Encoding for output" },
		{ "output", 'o', POPT_ARG_STRING, &output, 0, "Write output to this file" },
		{ "preload-modules", 'p', POPT_ARG_STRING, &preload_modules[0], 0, "Modules to load" },
		POPT_COMMON_SAMBA
		POPT_TABLEEND
	};

	setlinebuf(stdout);

	pc = poptGetContext("smbiconv", argc, (const char **) argv,
			    long_options, 0);

	poptSetOtherOptionHelp(pc, "[FILE] ...");
	
	while(poptGetNextOpt(pc) != -1);

	/* the following functions are part of the Samba debugging
	   facilities.  See lib/debug.c */
	setup_logging("smbiconv", True);

	if (preload_modules[0]) smb_load_modules(preload_modules);

	if(output) {
		out = fopen(output, "w");

		if(!out) {
			DEBUG(0, ("Can't open output file '%s': %s, exiting...\n", output, strerror(errno)));
			return 1;
		}
	}

	cd = smb_iconv_open(to, from);
	if((int)cd == -1) {
		DEBUG(0,("unable to find from or to encoding, exiting...\n"));
		return 1;
	}

	while((file = poptGetArg(pc))) {
		if(strcmp(file, "-") == 0) fd = 0;
		else {
			fd = open(file, O_RDONLY);
			
			if(!fd) {
				DEBUG(0, ("Can't open input file '%s': %s, ignoring...\n", file, strerror(errno)));
				continue;
			}
		}

		/* Loop thru all arguments */
		process_fd(cd, fd, out);

		close(fd);
	}
	poptFreeContext(pc);

	fclose(out);

	return 0;
}