diff options
Diffstat (limited to 'source3/lib')
-rw-r--r-- | source3/lib/charcnv.c | 1 | ||||
-rw-r--r-- | source3/lib/util.c | 10 | ||||
-rw-r--r-- | source3/lib/util_file.c | 35 | ||||
-rw-r--r-- | source3/lib/util_str.c | 12 | ||||
-rw-r--r-- | source3/lib/util_unistr.c | 139 |
5 files changed, 122 insertions, 75 deletions
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index 45d7d4d8d5..b7af6fef4b 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -101,6 +101,7 @@ size_t convert_string(charset_t from, charset_t to, if (!initialised) { initialised = 1; + load_case_tables(); init_iconv(); } diff --git a/source3/lib/util.c b/source3/lib/util.c index ce39bb3b1d..62e08333dd 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -1687,6 +1687,16 @@ char *lock_path(char *name) return fname; } +/***************************************************************** +a useful function for returning a path in the Samba lib directory + *****************************************************************/ +char *lib_path(char *name) +{ + static pstring fname; + snprintf(fname, sizeof(fname), "%s/%s", LIBDIR, name); + return fname; +} + /******************************************************************* Given a filename - get its directory name NB: Returned in static storage. Caveats: diff --git a/source3/lib/util_file.c b/source3/lib/util_file.c index 3d072bb170..77c0d7888e 100644 --- a/source3/lib/util_file.c +++ b/source3/lib/util_file.c @@ -422,6 +422,41 @@ char *file_load(const char *fname, size_t *size) } +/******************************************************************* +mmap (if possible) or read a file +********************************************************************/ +void *map_file(char *fname, size_t size) +{ + size_t s2 = 0; + void *p = NULL; +#ifdef HAVE_MMAP + int fd; + fd = open(fname, O_RDONLY, 0); + if (fd == -1) { + DEBUG(1,("Failed to load %s - %s\n", fname, strerror(errno))); + return NULL; + } + p = mmap(NULL, size, PROT_READ, MAP_SHARED|MAP_FILE, fd, 0); + close(fd); + if (p == MAP_FAILED) { + DEBUG(1,("Failed to mmap %s - %s\n", fname, strerror(errno))); + return NULL; + } +#endif + if (!p) { + p = file_load(fname, &s2); + if (!p || s2 != size) { + DEBUG(1,("incorrect size for %s - got %d expected %d\n", + fname, s2, size)); + if (p) free(p); + return NULL; + } + } + + return p; +} + + /**************************************************************************** parse a buffer into lines ****************************************************************************/ diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 0e7a7c02f5..3a77098e09 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -132,8 +132,8 @@ char **toktocliplist(int *ctok, char *sep) int StrCaseCmp(const char *s, const char *t) { pstring buf1, buf2; - unix_strlower(s, strlen(s)+1, buf1, sizeof(buf1)); - unix_strlower(t, strlen(t)+1, buf2, sizeof(buf2)); + unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1)); + unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2)); return strcmp(buf1,buf2); } @@ -142,10 +142,10 @@ int StrCaseCmp(const char *s, const char *t) ********************************************************************/ int StrnCaseCmp(const char *s, const char *t, size_t n) { - pstring buf1, buf2; - unix_strlower(s, strlen(s)+1, buf1, sizeof(buf1)); - unix_strlower(t, strlen(t)+1, buf2, sizeof(buf2)); - return strncmp(buf1,buf2,n); + pstring buf1, buf2; + unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1)); + unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2)); + return strncmp(buf1,buf2,n); } /******************************************************************* diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c index 1054eab6e1..a0e1b88eb8 100644 --- a/source3/lib/util_unistr.c +++ b/source3/lib/util_unistr.c @@ -25,6 +25,53 @@ #define MAXUNI 1024 #endif +/* these 3 tables define the unicode case handling. They are loaded + at startup either via mmap() or read() from the lib directory */ +static smb_ucs2_t *upcase_table; +static smb_ucs2_t *lowcase_table; +static uint8 *valid_table; + +/******************************************************************* +load the case handling tables +********************************************************************/ +void load_case_tables(void) +{ + static int initialised; + int i; + + if (initialised) return; + initialised = 1; + + 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 */ + if (!upcase_table) { + DEBUG(1,("creating lame upcase table\n")); + upcase_table = malloc(0x20000); + for (i=0;i<256;i++) upcase_table[i] = islower(i)?toupper(i):i; + for (;i<0x10000;i++) upcase_table[i] = i; + } + + if (!lowcase_table) { + DEBUG(1,("creating lame lowcase table\n")); + lowcase_table = malloc(0x20000); + for (i=0;i<256;i++) lowcase_table[i] = isupper(i)?tolower(i):i; + for (;i<0x10000;i++) lowcase_table[i] = i; + } + + if (!valid_table) { + DEBUG(1,("creating lame valid table\n")); + valid_table = malloc(0x10000); + for (i=0;i<256;i++) valid_table[i] = + isalnum(i) && !strchr("*\\/?<>|\":", i); + for (;i<0x10000;i++) valid_table[i] = 0; + } +} + + /******************************************************************* Write a string in (little-endian) unicode format. src is in the current DOS codepage. len is the length in bytes of the @@ -129,94 +176,46 @@ uint32 buffer2_to_uint32(BUFFER2 *str) } /******************************************************************* - Mapping tables for UNICODE character. Allows toupper/tolower and - isXXX functions to work. - - tridge: split into 2 pieces. This saves us 5/6 of the memory - with a small speed penalty - The magic constants are the lower/upper range of the tables two - parts + Convert a wchar to upper case. ********************************************************************/ -typedef struct { - smb_ucs2_t lower; - smb_ucs2_t upper; - unsigned char flags; -} smb_unicode_table_t; - -#define TABLE1_BOUNDARY 9450 -#define TABLE2_BOUNDARY 64256 - -static smb_unicode_table_t map_table1[] = { -#include "unicode_map_table1.h" -}; - -static smb_unicode_table_t map_table2[] = { -#include "unicode_map_table2.h" -}; - -static unsigned char map_table_flags(smb_ucs2_t v) -{ - v = SVAL(&v,0); - if (v < TABLE1_BOUNDARY) return map_table1[v].flags; - if (v >= TABLE2_BOUNDARY) return map_table2[v - TABLE2_BOUNDARY].flags; - return 0; -} - -static smb_ucs2_t map_table_lower(smb_ucs2_t v) -{ - v = SVAL(&v,0); - if (v < TABLE1_BOUNDARY) return map_table1[v].lower; - if (v >= TABLE2_BOUNDARY) return map_table2[v - TABLE2_BOUNDARY].lower; - return v; -} - -static smb_ucs2_t map_table_upper(smb_ucs2_t v) +smb_ucs2_t toupper_w(smb_ucs2_t val) { - v = SVAL(&v,0); - if (v < TABLE1_BOUNDARY) return map_table1[v].upper; - if (v >= TABLE2_BOUNDARY) return map_table2[v - TABLE2_BOUNDARY].upper; - return v; + return upcase_table[val]; } /******************************************************************* - Is an upper case wchar. + Convert a wchar to lower case. ********************************************************************/ -int isupper_w( smb_ucs2_t val) +smb_ucs2_t tolower_w( smb_ucs2_t val ) { - return (map_table_flags(val) & UNI_UPPER); + return lowcase_table[val]; } /******************************************************************* - Is a lower case wchar. +determine if a character is lowercase ********************************************************************/ - -int islower_w( smb_ucs2_t val) +BOOL islower_w(smb_ucs2_t c) { - return (map_table_flags(val) & UNI_LOWER); + return upcase_table[c] != c; } /******************************************************************* - Convert a wchar to upper case. +determine if a character is uppercase ********************************************************************/ - -smb_ucs2_t toupper_w( smb_ucs2_t val ) +BOOL isupper_w(smb_ucs2_t c) { - val = map_table_upper(val); - val = SVAL(&val,0); - return val; + return lowcase_table[c] != c; } + /******************************************************************* - Convert a wchar to lower case. +determine if a character is valid in a 8.3 name ********************************************************************/ - -smb_ucs2_t tolower_w( smb_ucs2_t val ) +BOOL isvalid83_w(smb_ucs2_t c) { - val = map_table_lower(val); - val = SVAL(&val,0); - return val; + return valid_table[c] != 0; } /******************************************************************* @@ -252,8 +251,9 @@ BOOL strlower_w(smb_ucs2_t *s) { BOOL ret = False; while (*s) { - if (isupper_w(*s)) { - *s = tolower_w(*s); + smb_ucs2_t v = tolower_w(*s); + if (v != *s) { + *s = v; ret = True; } s++; @@ -269,8 +269,9 @@ BOOL strupper_w(smb_ucs2_t *s) { BOOL ret = False; while (*s) { - if (islower_w(*s)) { - *s = toupper_w(*s); + smb_ucs2_t v = toupper_w(*s); + if (v != *s) { + *s = v; ret = True; } s++; @@ -283,7 +284,7 @@ case insensitive string comparison ********************************************************************/ int strcasecmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b) { - while (*b && tolower_w(*a) == tolower_w(*b)) { a++; b++; } + while (*b && toupper_w(*a) == toupper_w(*b)) { a++; b++; } return (tolower_w(*a) - tolower_w(*b)); } |