関数 | |
| static unsigned int | mangle_hash (const char *key, unsigned int length) |
| static BOOL | cache_init (void) |
| static void | cache_insert (const char *prefix, int length, unsigned int hash) |
| static const char * | cache_lookup (unsigned int hash) |
| static BOOL | is_mangled_component (const char *name, size_t len) |
| static BOOL | is_mangled (const char *name, const struct share_params *parm) |
| static BOOL | is_8_3 (const char *name, BOOL check_case, BOOL allow_wildcards, const struct share_params *p) |
| static void | mangle_reset (void) |
| static BOOL | check_cache (char *name, size_t maxlen, const struct share_params *p) |
| static BOOL | is_reserved_name (const char *name) |
| static BOOL | is_legal_name (const char *name) |
| static void | name_map (fstring name, BOOL need83, BOOL cache83, int default_case, const struct share_params *p) |
| static void | init_tables (void) |
| mangle_fns * | mangle_hash2_init (void) |
| static void | posix_mangle_reset (void) |
| static BOOL | posix_is_mangled (const char *s, const struct share_params *p) |
| static BOOL | posix_is_8_3 (const char *fname, BOOL check_case, BOOL allow_wildcards, const struct share_params *p) |
| static BOOL | posix_check_cache (char *s, size_t maxlen, const struct share_params *p) |
| static void | posix_name_map (char *OutName, BOOL need83, BOOL cache83, int default_case, const struct share_params *p) |
| mangle_fns * | posix_mangle_init (void) |
変数 | |
| static unsigned char | char_flags [256] |
| static unsigned | mangle_prefix |
| static char ** | prefix_cache |
| static unsigned int * | prefix_cache_hashes |
| static const char * | basechars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| static unsigned char | base_reverse [256] |
| static const char * | reserved_names [] |
| static struct mangle_fns | mangle_fns |
| static struct mangle_fns | posix_mangle_fns |
| static unsigned int mangle_hash | ( | const char * | key, | |
| unsigned int | length | |||
| ) | [static] |
mangle_hash2.c の 122 行で定義されています。
参照先 strupper_m().
参照元 name_map().
00123 { 00124 unsigned int value; 00125 unsigned int i; 00126 fstring str; 00127 00128 /* we have to uppercase here to ensure that the mangled name 00129 doesn't depend on the case of the long name. Note that this 00130 is the only place where we need to use a multi-byte string 00131 function */ 00132 length = MIN(length,sizeof(fstring)-1); 00133 strncpy(str, key, length); 00134 str[length] = 0; 00135 strupper_m(str); 00136 00137 /* the length of a multi-byte string can change after a strupper_m */ 00138 length = strlen(str); 00139 00140 /* Set the initial value from the key size. */ 00141 for (value = FNV1_INIT, i=0; i < length; i++) { 00142 value *= (unsigned int)FNV1_PRIME; 00143 value ^= (unsigned int)(str[i]); 00144 } 00145 00146 /* note that we force it to a 31 bit hash, to keep within the limits 00147 of the 36^6 mangle space */ 00148 return value & ~0x80000000; 00149 }
| static BOOL cache_init | ( | void | ) | [static] |
mangle_hash2.c の 154 行で定義されています。
参照先 prefix_cache・prefix_cache_hashes.
参照元 mangle_hash2_init().
00155 { 00156 if (prefix_cache) { 00157 return True; 00158 } 00159 00160 prefix_cache = SMB_CALLOC_ARRAY(char *,MANGLE_CACHE_SIZE); 00161 if (!prefix_cache) { 00162 return False; 00163 } 00164 00165 prefix_cache_hashes = SMB_CALLOC_ARRAY(unsigned int, MANGLE_CACHE_SIZE); 00166 if (!prefix_cache_hashes) { 00167 return False; 00168 } 00169 00170 return True; 00171 }
| static void cache_insert | ( | const char * | prefix, | |
| int | length, | |||
| unsigned int | hash | |||
| ) | [static] |
mangle_hash2.c の 176 行で定義されています。
参照先 prefix_cache・prefix_cache_hashes.
参照元 name_map().
00177 { 00178 int i = hash % MANGLE_CACHE_SIZE; 00179 00180 if (prefix_cache[i]) { 00181 free(prefix_cache[i]); 00182 } 00183 00184 prefix_cache[i] = SMB_STRNDUP(prefix, length); 00185 prefix_cache_hashes[i] = hash; 00186 }
| static const char* cache_lookup | ( | unsigned int | hash | ) | [static] |
mangle_hash2.c の 191 行で定義されています。
参照先 prefix_cache・prefix_cache_hashes.
参照元 check_cache().
00192 { 00193 int i = hash % MANGLE_CACHE_SIZE; 00194 00195 if (!prefix_cache[i] || hash != prefix_cache_hashes[i]) { 00196 return NULL; 00197 } 00198 00199 /* yep, it matched */ 00200 return prefix_cache[i]; 00201 }
| static BOOL is_mangled_component | ( | const char * | name, | |
| size_t | len | |||
| ) | [static] |
mangle_hash2.c の 211 行で定義されています。
参照先 mangle_prefix.
参照元 is_mangled().
00212 { 00213 unsigned int i; 00214 00215 M_DEBUG(10,("is_mangled_component %s (len %lu) ?\n", name, (unsigned long)len)); 00216 00217 /* check the length */ 00218 if (len > 12 || len < 8) 00219 return False; 00220 00221 /* the best distinguishing characteristic is the ~ */ 00222 if (name[6] != '~') 00223 return False; 00224 00225 /* check extension */ 00226 if (len > 8) { 00227 if (name[8] != '.') 00228 return False; 00229 for (i=9; name[i] && i < len; i++) { 00230 if (! FLAG_CHECK(name[i], FLAG_ASCII)) { 00231 return False; 00232 } 00233 } 00234 } 00235 00236 /* check lead characters */ 00237 for (i=0;i<mangle_prefix;i++) { 00238 if (! FLAG_CHECK(name[i], FLAG_ASCII)) { 00239 return False; 00240 } 00241 } 00242 00243 /* check rest of hash */ 00244 if (! FLAG_CHECK(name[7], FLAG_BASECHAR)) { 00245 return False; 00246 } 00247 for (i=mangle_prefix;i<6;i++) { 00248 if (! FLAG_CHECK(name[i], FLAG_BASECHAR)) { 00249 return False; 00250 } 00251 } 00252 00253 M_DEBUG(10,("is_mangled_component %s (len %lu) -> yes\n", name, (unsigned long)len)); 00254 00255 return True; 00256 }
| static BOOL is_mangled | ( | const char * | name, | |
| const struct share_params * | parm | |||
| ) | [static] |
mangle_hash2.c の 271 行で定義されています。
00272 { 00273 const char *p; 00274 const char *s; 00275 00276 M_DEBUG(10,("is_mangled %s ?\n", name)); 00277 00278 for (s=name; (p=strchr(s, '/')); s=p+1) { 00279 if (is_mangled_component(s, PTR_DIFF(p, s))) { 00280 return True; 00281 } 00282 } 00283 00284 /* and the last part ... */ 00285 return is_mangled_component(s,strlen(s)); 00286 }
| static BOOL is_8_3 | ( | const char * | name, | |
| BOOL | check_case, | |||
| BOOL | allow_wildcards, | |||
| const struct share_params * | p | |||
| ) | [static] |
mangle_hash2.c の 296 行で定義されています。
参照先 len.
00297 { 00298 int len, i; 00299 char *dot_p; 00300 00301 /* as a special case, the names '.' and '..' are allowable 8.3 names */ 00302 if (name[0] == '.') { 00303 if (!name[1] || (name[1] == '.' && !name[2])) { 00304 return True; 00305 } 00306 } 00307 00308 /* the simplest test is on the overall length of the 00309 filename. Note that we deliberately use the ascii string 00310 length (not the multi-byte one) as it is faster, and gives us 00311 the result we need in this case. Using strlen_m would not 00312 only be slower, it would be incorrect */ 00313 len = strlen(name); 00314 if (len > 12) 00315 return False; 00316 00317 /* find the '.'. Note that once again we use the non-multibyte 00318 function */ 00319 dot_p = strchr(name, '.'); 00320 00321 if (!dot_p) { 00322 /* if the name doesn't contain a '.' then its length 00323 must be less than 8 */ 00324 if (len > 8) { 00325 return False; 00326 } 00327 } else { 00328 int prefix_len, suffix_len; 00329 00330 /* if it does contain a dot then the prefix must be <= 00331 8 and the suffix <= 3 in length */ 00332 prefix_len = PTR_DIFF(dot_p, name); 00333 suffix_len = len - (prefix_len+1); 00334 00335 if (prefix_len > 8 || suffix_len > 3 || suffix_len == 0) { 00336 return False; 00337 } 00338 00339 /* a 8.3 name cannot contain more than 1 '.' */ 00340 if (strchr(dot_p+1, '.')) { 00341 return False; 00342 } 00343 } 00344 00345 /* the length are all OK. Now check to see if the characters themselves are OK */ 00346 for (i=0; name[i]; i++) { 00347 /* note that we may allow wildcard petterns! */ 00348 if (!FLAG_CHECK(name[i], FLAG_ASCII|(allow_wildcards ? FLAG_WILDCARD : 0)) && name[i] != '.') { 00349 return False; 00350 } 00351 } 00352 00353 /* it is a good 8.3 name */ 00354 return True; 00355 }
| static void mangle_reset | ( | void | ) | [static] |
| static BOOL check_cache | ( | char * | name, | |
| size_t | maxlen, | |||
| const struct share_params * | p | |||
| ) | [static] |
mangle_hash2.c の 373 行で定義されています。
参照先 base_reverse・cache_lookup()・is_mangled()・mangle_prefix.
00374 { 00375 unsigned int hash, multiplier; 00376 unsigned int i; 00377 const char *prefix; 00378 char extension[4]; 00379 00380 /* make sure that this is a mangled name from this cache */ 00381 if (!is_mangled(name, p)) { 00382 M_DEBUG(10,("check_cache: %s -> not mangled\n", name)); 00383 return False; 00384 } 00385 00386 /* we need to extract the hash from the 8.3 name */ 00387 hash = base_reverse[(unsigned char)name[7]]; 00388 for (multiplier=36, i=5;i>=mangle_prefix;i--) { 00389 unsigned int v = base_reverse[(unsigned char)name[i]]; 00390 hash += multiplier * v; 00391 multiplier *= 36; 00392 } 00393 00394 /* now look in the prefix cache for that hash */ 00395 prefix = cache_lookup(hash); 00396 if (!prefix) { 00397 M_DEBUG(10,("check_cache: %s -> %08X -> not found\n", name, hash)); 00398 return False; 00399 } 00400 00401 /* we found it - construct the full name */ 00402 if (name[8] == '.') { 00403 strncpy(extension, name+9, 3); 00404 extension[3] = 0; 00405 } else { 00406 extension[0] = 0; 00407 } 00408 00409 if (extension[0]) { 00410 M_DEBUG(10,("check_cache: %s -> %s.%s\n", name, prefix, extension)); 00411 slprintf(name, maxlen, "%s.%s", prefix, extension); 00412 } else { 00413 M_DEBUG(10,("check_cache: %s -> %s\n", name, prefix)); 00414 safe_strcpy(name, prefix, maxlen); 00415 } 00416 00417 return True; 00418 }
| static BOOL is_reserved_name | ( | const char * | name | ) | [static] |
mangle_hash2.c の 424 行で定義されています。
参照先 len・reserved_names・strnequal().
参照元 name_map().
00425 { 00426 if (FLAG_CHECK(name[0], FLAG_POSSIBLE1) && 00427 FLAG_CHECK(name[1], FLAG_POSSIBLE2) && 00428 FLAG_CHECK(name[2], FLAG_POSSIBLE3) && 00429 FLAG_CHECK(name[3], FLAG_POSSIBLE4)) { 00430 /* a likely match, scan the lot */ 00431 int i; 00432 for (i=0; reserved_names[i]; i++) { 00433 int len = strlen(reserved_names[i]); 00434 /* note that we match on COM1 as well as COM1.foo */ 00435 if (strnequal(name, reserved_names[i], len) && 00436 (name[len] == '.' || name[len] == 0)) { 00437 return True; 00438 } 00439 } 00440 } 00441 00442 return False; 00443 }
| static BOOL is_legal_name | ( | const char * | name | ) | [static] |
mangle_hash2.c の 451 行で定義されています。
参照先 CH_UNIX・CH_UTF16LE・convert_string().
参照元 name_map().
00452 { 00453 const char *dot_pos = NULL; 00454 BOOL alldots = True; 00455 size_t numdots = 0; 00456 00457 while (*name) { 00458 if (((unsigned int)name[0]) > 128 && (name[1] != 0)) { 00459 /* Possible start of mb character. */ 00460 char mbc[2]; 00461 /* 00462 * Note that if CH_UNIX is utf8 a string may be 3 00463 * bytes, but this is ok as mb utf8 characters don't 00464 * contain embedded ascii bytes. We are really checking 00465 * for mb UNIX asian characters like Japanese (SJIS) here. 00466 * JRA. 00467 */ 00468 if (convert_string(CH_UNIX, CH_UTF16LE, name, 2, mbc, 2, False) == 2) { 00469 /* Was a good mb string. */ 00470 name += 2; 00471 continue; 00472 } 00473 } 00474 00475 if (FLAG_CHECK(name[0], FLAG_ILLEGAL)) { 00476 return False; 00477 } 00478 if (name[0] == '.') { 00479 dot_pos = name; 00480 numdots++; 00481 } else { 00482 alldots = False; 00483 } 00484 if ((name[0] == ' ') && (name[1] == '\0')) { 00485 /* Can't end in ' ' */ 00486 return False; 00487 } 00488 name++; 00489 } 00490 00491 if (dot_pos) { 00492 if (alldots && (numdots == 1 || numdots == 2)) 00493 return True; /* . or .. is a valid name */ 00494 00495 /* A valid long name cannot end in '.' */ 00496 if (dot_pos[1] == '\0') 00497 return False; 00498 } 00499 return True; 00500 }
| static void name_map | ( | fstring | name, | |
| BOOL | need83, | |||
| BOOL | cache83, | |||
| int | default_case, | |||
| const struct share_params * | p | |||
| ) | [static] |
mangle_hash2.c の 513 行で定義されています。
参照先 c・cache_insert()・is_8_3()・is_legal_name()・is_reserved_name()・mangle_hash()・mangle_prefix・toupper_ascii().
00514 { 00515 char *dot_p; 00516 char lead_chars[7]; 00517 char extension[4]; 00518 unsigned int extension_length, i; 00519 unsigned int prefix_len; 00520 unsigned int hash, v; 00521 char new_name[13]; 00522 00523 /* reserved names are handled specially */ 00524 if (!is_reserved_name(name)) { 00525 /* if the name is already a valid 8.3 name then we don't need to 00526 do anything */ 00527 if (is_8_3(name, False, False, p)) { 00528 return; 00529 } 00530 00531 /* if the caller doesn't strictly need 8.3 then just check for illegal 00532 filenames */ 00533 if (!need83 && is_legal_name(name)) { 00534 return; 00535 } 00536 } 00537 00538 /* find the '.' if any */ 00539 dot_p = strrchr(name, '.'); 00540 00541 if (dot_p) { 00542 /* if the extension contains any illegal characters or 00543 is too long or zero length then we treat it as part 00544 of the prefix */ 00545 for (i=0; i<4 && dot_p[i+1]; i++) { 00546 if (! FLAG_CHECK(dot_p[i+1], FLAG_ASCII)) { 00547 dot_p = NULL; 00548 break; 00549 } 00550 } 00551 if (i == 0 || i == 4) dot_p = NULL; 00552 } 00553 00554 /* the leading characters in the mangled name is taken from 00555 the first characters of the name, if they are ascii otherwise 00556 '_' is used 00557 */ 00558 for (i=0;i<mangle_prefix && name[i];i++) { 00559 lead_chars[i] = name[i]; 00560 if (! FLAG_CHECK(lead_chars[i], FLAG_ASCII)) { 00561 lead_chars[i] = '_'; 00562 } 00563 lead_chars[i] = toupper_ascii(lead_chars[i]); 00564 } 00565 for (;i<mangle_prefix;i++) { 00566 lead_chars[i] = '_'; 00567 } 00568 00569 /* the prefix is anything up to the first dot */ 00570 if (dot_p) { 00571 prefix_len = PTR_DIFF(dot_p, name); 00572 } else { 00573 prefix_len = strlen(name); 00574 } 00575 00576 /* the extension of the mangled name is taken from the first 3 00577 ascii chars after the dot */ 00578 extension_length = 0; 00579 if (dot_p) { 00580 for (i=1; extension_length < 3 && dot_p[i]; i++) { 00581 char c = dot_p[i]; 00582 if (FLAG_CHECK(c, FLAG_ASCII)) { 00583 extension[extension_length++] = toupper_ascii(c); 00584 } 00585 } 00586 } 00587 00588 /* find the hash for this prefix */ 00589 v = hash = mangle_hash(name, prefix_len); 00590 00591 /* now form the mangled name. */ 00592 for (i=0;i<mangle_prefix;i++) { 00593 new_name[i] = lead_chars[i]; 00594 } 00595 new_name[7] = base_forward(v % 36); 00596 new_name[6] = '~'; 00597 for (i=5; i>=mangle_prefix; i--) { 00598 v = v / 36; 00599 new_name[i] = base_forward(v % 36); 00600 } 00601 00602 /* add the extension */ 00603 if (extension_length) { 00604 new_name[8] = '.'; 00605 memcpy(&new_name[9], extension, extension_length); 00606 new_name[9+extension_length] = 0; 00607 } else { 00608 new_name[8] = 0; 00609 } 00610 00611 if (cache83) { 00612 /* put it in the cache */ 00613 cache_insert(name, prefix_len, hash); 00614 } 00615 00616 M_DEBUG(10,("name_map: %s -> %08X -> %s (cache=%d)\n", 00617 name, hash, new_name, cache83)); 00618 00619 /* and overwrite the old name */ 00620 fstrcpy(name, new_name); 00621 00622 /* all done, we've managed to mangle it */ 00623 }
| static void init_tables | ( | void | ) | [static] |
mangle_hash2.c の 633 行で定義されています。
参照先 base_reverse・char_flags・reserved_names・tolower_ascii().
参照元 mangle_hash2_init().
00634 { 00635 int i; 00636 00637 memset(char_flags, 0, sizeof(char_flags)); 00638 00639 for (i=1;i<128;i++) { 00640 if (i <= 0x1f) { 00641 /* Control characters. */ 00642 char_flags[i] |= FLAG_ILLEGAL; 00643 } 00644 00645 if ((i >= '0' && i <= '9') || 00646 (i >= 'a' && i <= 'z') || 00647 (i >= 'A' && i <= 'Z')) { 00648 char_flags[i] |= (FLAG_ASCII | FLAG_BASECHAR); 00649 } 00650 if (strchr("_-$~", i)) { 00651 char_flags[i] |= FLAG_ASCII; 00652 } 00653 00654 if (strchr("*\\/?<>|\":", i)) { 00655 char_flags[i] |= FLAG_ILLEGAL; 00656 } 00657 00658 if (strchr("*?\"<>", i)) { 00659 char_flags[i] |= FLAG_WILDCARD; 00660 } 00661 } 00662 00663 memset(base_reverse, 0, sizeof(base_reverse)); 00664 for (i=0;i<36;i++) { 00665 base_reverse[(unsigned char)base_forward(i)] = i; 00666 } 00667 00668 /* fill in the reserved names flags. These are used as a very 00669 fast filter for finding possible DOS reserved filenames */ 00670 for (i=0; reserved_names[i]; i++) { 00671 unsigned char c1, c2, c3, c4; 00672 00673 c1 = (unsigned char)reserved_names[i][0]; 00674 c2 = (unsigned char)reserved_names[i][1]; 00675 c3 = (unsigned char)reserved_names[i][2]; 00676 c4 = (unsigned char)reserved_names[i][3]; 00677 00678 char_flags[c1] |= FLAG_POSSIBLE1; 00679 char_flags[c2] |= FLAG_POSSIBLE2; 00680 char_flags[c3] |= FLAG_POSSIBLE3; 00681 char_flags[c4] |= FLAG_POSSIBLE4; 00682 char_flags[tolower_ascii(c1)] |= FLAG_POSSIBLE1; 00683 char_flags[tolower_ascii(c2)] |= FLAG_POSSIBLE2; 00684 char_flags[tolower_ascii(c3)] |= FLAG_POSSIBLE3; 00685 char_flags[tolower_ascii(c4)] |= FLAG_POSSIBLE4; 00686 00687 char_flags[(unsigned char)'.'] |= FLAG_POSSIBLE4; 00688 } 00689 }
| struct mangle_fns* mangle_hash2_init | ( | void | ) |
mangle_hash2.c の 703 行で定義されています。
参照先 cache_init()・init_tables()・mangle_fns・mangle_prefix・mangle_reset().
00704 { 00705 /* the mangle prefix can only be in the mange 1 to 6 */ 00706 mangle_prefix = lp_mangle_prefix(); 00707 if (mangle_prefix > 6) { 00708 mangle_prefix = 6; 00709 } 00710 if (mangle_prefix < 1) { 00711 mangle_prefix = 1; 00712 } 00713 00714 init_tables(); 00715 mangle_reset(); 00716 00717 if (!cache_init()) { 00718 return NULL; 00719 } 00720 00721 return &mangle_fns; 00722 }
| static void posix_mangle_reset | ( | void | ) | [static] |
| static BOOL posix_is_mangled | ( | const char * | s, | |
| const struct share_params * | p | |||
| ) | [static] |
| static BOOL posix_is_8_3 | ( | const char * | fname, | |
| BOOL | check_case, | |||
| BOOL | allow_wildcards, | |||
| const struct share_params * | p | |||
| ) | [static] |
| static BOOL posix_check_cache | ( | char * | s, | |
| size_t | maxlen, | |||
| const struct share_params * | p | |||
| ) | [static] |
| static void posix_name_map | ( | char * | OutName, | |
| BOOL | need83, | |||
| BOOL | cache83, | |||
| int | default_case, | |||
| const struct share_params * | p | |||
| ) | [static] |
| struct mangle_fns* posix_mangle_init | ( | void | ) |
mangle_hash2.c の 758 行で定義されています。
参照先 posix_mangle_fns.
00759 { 00760 return &posix_mangle_fns; 00761 }
unsigned char char_flags[256] [static] |
unsigned mangle_prefix [static] |
mangle_hash2.c の 95 行で定義されています。
参照元 check_cache()・is_mangled_component()・mangle_hash2_init()・name_map().
char** prefix_cache [static] |
unsigned int* prefix_cache_hashes [static] |
const char* basechars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" [static] |
mangle_hash2.c の 107 行で定義されています。
unsigned char base_reverse[256] [static] |
const char* reserved_names[] [static] |
初期値:
{ "AUX", "LOCK$", "CON", "COM1", "COM2", "COM3", "COM4",
"LPT1", "LPT2", "LPT3", "NUL", "PRN", NULL }
mangle_hash2.c の 112 行で定義されています。
struct mangle_fns mangle_fns [static] |
struct mangle_fns posix_mangle_fns [static] |
1.4.7