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 */
for (c2=0;c2<NUM_CHARSETS;c2++) {
char *n1 = charset_name((charset_t)c1);
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]);
}
}
}
}
+
+ if (did_reload) {
+ init_valid_table();
+ }
}
/**
initialized = 1;
load_case_tables();
init_iconv();
+ init_valid_table();
}
descriptor = conv_handles[from][to];
break;
case EILSEQ: reason="Illegal myltibyte sequence"; break;
}
- DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf));
/* smb_panic(reason); */
}
return destlen-o_len;
}
memset(ret, 0, sizeof(*ret));
+ ret->from_name = strdup(fromcode);
+ ret->to_name = strdup(tocode);
+
/* check for the simplest null conversion */
if (strcmp(fromcode, tocode) == 0) {
ret->direct = iconv_copy;
if (cd->cd_push) iconv_close((iconv_t)cd->cd_push);
#endif
+ SAFE_FREE(cd->from_name);
+ SAFE_FREE(cd->to_name);
+
memset(cd, 0, sizeof(*cd));
SAFE_FREE(cd);
return 0;
int ir_count=0;
while (*inbytesleft >= 2 && *outbytesleft >= 1) {
- (*outbuf)[0] = (*inbuf)[0];
+ (*outbuf)[0] = (*inbuf)[0] & 0x7F;
if ((*inbuf)[1]) ir_count++;
(*inbytesleft) -= 2;
(*outbytesleft) -= 1;
static smb_ucs2_t *lowcase_table;
static uint8 *valid_table;
+
/*******************************************************************
load the case handling tables
********************************************************************/
upcase_table = map_file(lib_path("upcase.dat"), 0x20000);
lowcase_table = map_file(lib_path("lowcase.dat"), 0x20000);
- valid_table = map_file(lib_path("valid.dat"), 0x10000);
/* we would like Samba to limp along even if these tables are
not available */
for (i=0;i<0x10000;i++) lowcase_table[i] = i;
for (i=0;i<256;i++) lowcase_table[UCS2_CHAR(i)] = UCS2_CHAR(isupper(i)?tolower(i):i);
}
+}
+
+/*
+ see if a ucs2 character can be mapped correctly to a dos character
+ and mapped back to the same character in ucs2
+*/
+static int check_dos_char(smb_ucs2_t c)
+{
+ char buf[10];
+ smb_ucs2_t c2 = 0;
+ int len1, len2;
+ len1 = convert_string(CH_UCS2, CH_DOS, &c, 2, buf, sizeof(buf));
+ if (len1 == 0) return 0;
+ len2 = convert_string(CH_DOS, CH_UCS2, buf, len1, &c2, 2);
+ if (len2 != 2) return 0;
+ return (c == c2);
+}
+
+/*******************************************************************
+load the valid character map table
+********************************************************************/
+void init_valid_table(void)
+{
+ static int initialised;
+ static int mapped_file;
+ int i;
+ const char *allowed = ".!#$%&'()_-@^`~";
+
+ if (initialised && mapped_file) return;
+ initialised = 1;
- if (!valid_table) {
- const char *allowed = ".!#$%&'()_-@^`~";
- DEBUG(1,("creating lame valid table\n"));
- valid_table = malloc(0x10000);
- for (i=0;i<0x10000;i++) valid_table[i] = 0;
- for (i=0;i<256;i++) valid_table[UCS2_CHAR(i)] = isalnum(i) || strchr(allowed,i);
+ valid_table = map_file(lib_path("valid.dat"), 0x10000);
+ if (valid_table) {
+ mapped_file = 1;
+ return;
}
+
+ if (valid_table) free(valid_table);
+
+ DEBUG(2,("creating default valid table\n"));
+ valid_table = malloc(0x10000);
+ for (i=0;i<128;i++) valid_table[UCS2_CHAR(i)] = isalnum(i) ||
+ strchr(allowed,i);
+ for (;i<0x10000;i++) valid_table[UCS2_CHAR(i)] = check_dos_char(i);
}