much better auto-init of valid_table[]. This should just about remove
authorAndrew Tridgell <tridge@samba.org>
Thu, 20 Dec 2001 06:18:52 +0000 (06:18 +0000)
committerAndrew Tridgell <tridge@samba.org>
Thu, 20 Dec 2001 06:18:52 +0000 (06:18 +0000)
the need for valid.dat

source/include/smb.h
source/lib/charcnv.c
source/lib/iconv.c
source/lib/util_unistr.c

index ae2727268d3418861f71bbf25c6e4f2089f8fe55..8c0491a004b88deccb99fab9f7e16036434f8faf 100644 (file)
@@ -1654,6 +1654,7 @@ typedef struct {
        size_t (*push)(void *cd, char **inbuf, size_t *inbytesleft,
                       char **outbuf, size_t *outbytesleft);
        void *cd_direct, *cd_pull, *cd_push;
+       char *from_name, *to_name;
 } *smb_iconv_t;
 
 /* The maximum length of a trust account password.
index 2e5413c5c0b6b42f4434abaf8bdae7e46f5e3bc2..256bd7e88c736754efb4927e51b227f3bf37a76f 100644 (file)
@@ -51,6 +51,7 @@ static char *charset_name(charset_t ch)
 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 */
@@ -66,6 +67,12 @@ void init_iconv(void)
                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]);
                        }
@@ -77,6 +84,10 @@ void init_iconv(void)
                        }
                }
        }
+
+       if (did_reload) {
+               init_valid_table();
+       }
 }
 
 /**
@@ -105,6 +116,7 @@ size_t convert_string(charset_t from, charset_t to,
                initialized = 1;
                load_case_tables();
                init_iconv();
+               init_valid_table();
        }
 
        descriptor = conv_handles[from][to];
@@ -136,7 +148,6 @@ size_t convert_string(charset_t from, charset_t 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;
index 8bcd92d72a3f28f74412e8ce14a050a7d19b3aae..c08524eaa03aae5c8703313d876b3ae9f8b14e3e 100644 (file)
@@ -125,6 +125,9 @@ smb_iconv_t smb_iconv_open(const char *tocode, const char *fromcode)
        }
        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;
@@ -202,6 +205,9 @@ int smb_iconv_close (smb_iconv_t cd)
        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;
@@ -240,7 +246,7 @@ static size_t ascii_push(void *cd, char **inbuf, size_t *inbytesleft,
        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;
index 6034a715d31aa6dc19b72eef8a4bd5c0def35aeb..08fc1760ae813c2e895b4b022dbf6ee55a8c6f11 100644 (file)
@@ -32,6 +32,7 @@ static smb_ucs2_t *upcase_table;
 static smb_ucs2_t *lowcase_table;
 static uint8 *valid_table;
 
+
 /*******************************************************************
 load the case handling tables
 ********************************************************************/
@@ -45,7 +46,6 @@ void load_case_tables(void)
 
        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 */
@@ -62,14 +62,50 @@ void load_case_tables(void)
                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);
 }