/** * 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; } }
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; }
/** * 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; }
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; }