smbd/mangle_hash2.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    new hash based name mangling implementation
00004    Copyright (C) Andrew Tridgell 2002
00005    Copyright (C) Simo Sorce 2002
00006    
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011    
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016    
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00020 */
00021 
00022 /*
00023   this mangling scheme uses the following format
00024 
00025   Annnn~n.AAA
00026 
00027   where nnnnn is a base 36 hash, and A represents characters from the original string
00028 
00029   The hash is taken of the leading part of the long filename, in uppercase
00030 
00031   for simplicity, we only allow ascii characters in 8.3 names
00032  */
00033 
00034  /* hash alghorithm changed to FNV1 by idra@samba.org (Simo Sorce).
00035   * see http://www.isthe.com/chongo/tech/comp/fnv/index.html for a
00036   * discussion on Fowler / Noll / Vo (FNV) Hash by one of it's authors
00037   */
00038 
00039 /*
00040   ===============================================================================
00041   NOTE NOTE NOTE!!!
00042 
00043   This file deliberately uses non-multibyte string functions in many places. This
00044   is *not* a mistake. This code is multi-byte safe, but it gets this property
00045   through some very subtle knowledge of the way multi-byte strings are encoded 
00046   and the fact that this mangling algorithm only supports ascii characters in
00047   8.3 names.
00048 
00049   please don't convert this file to use the *_m() functions!!
00050   ===============================================================================
00051 */
00052 
00053 
00054 #include "includes.h"
00055 
00056 #if 1
00057 #define M_DEBUG(level, x) DEBUG(level, x)
00058 #else
00059 #define M_DEBUG(level, x)
00060 #endif
00061 
00062 /* these flags are used to mark characters in as having particular
00063    properties */
00064 #define FLAG_BASECHAR 1
00065 #define FLAG_ASCII 2
00066 #define FLAG_ILLEGAL 4
00067 #define FLAG_WILDCARD 8
00068 
00069 /* the "possible" flags are used as a fast way to find possible DOS
00070    reserved filenames */
00071 #define FLAG_POSSIBLE1 16
00072 #define FLAG_POSSIBLE2 32
00073 #define FLAG_POSSIBLE3 64
00074 #define FLAG_POSSIBLE4 128
00075 
00076 /* by default have a max of 4096 entries in the cache. */
00077 #ifndef MANGLE_CACHE_SIZE
00078 #define MANGLE_CACHE_SIZE 4096
00079 #endif
00080 
00081 #define FNV1_PRIME 0x01000193
00082 /*the following number is a fnv1 of the string: idra@samba.org 2002 */
00083 #define FNV1_INIT  0xa6b93095
00084 
00085 /* these tables are used to provide fast tests for characters */
00086 static unsigned char char_flags[256];
00087 
00088 #define FLAG_CHECK(c, flag) (char_flags[(unsigned char)(c)] & (flag))
00089 
00090 /*
00091   this determines how many characters are used from the original filename
00092   in the 8.3 mangled name. A larger value leads to a weaker hash and more collisions.
00093   The largest possible value is 6.
00094 */
00095 static unsigned mangle_prefix;
00096 
00097 /* we will use a very simple direct mapped prefix cache. The big
00098    advantage of this cache structure is speed and low memory usage 
00099 
00100    The cache is indexed by the low-order bits of the hash, and confirmed by
00101    hashing the resulting cache entry to match the known hash
00102 */
00103 static char **prefix_cache;
00104 static unsigned int *prefix_cache_hashes;
00105 
00106 /* these are the characters we use in the 8.3 hash. Must be 36 chars long */
00107 static const char *basechars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
00108 static unsigned char base_reverse[256];
00109 #define base_forward(v) basechars[v]
00110 
00111 /* the list of reserved dos names - all of these are illegal */
00112 static const char *reserved_names[] = 
00113 { "AUX", "LOCK$", "CON", "COM1", "COM2", "COM3", "COM4",
00114   "LPT1", "LPT2", "LPT3", "NUL", "PRN", NULL };
00115 
00116 /* 
00117    hash a string of the specified length. The string does not need to be
00118    null terminated 
00119 
00120    this hash needs to be fast with a low collision rate (what hash doesn't?)
00121 */
00122 static unsigned int mangle_hash(const char *key, unsigned int length)
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 }
00150 
00151 /* 
00152    initialise (ie. allocate) the prefix cache
00153  */
00154 static BOOL cache_init(void)
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 }
00172 
00173 /*
00174   insert an entry into the prefix cache. The string might not be null
00175   terminated */
00176 static void cache_insert(const char *prefix, int length, unsigned int hash)
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 }
00187 
00188 /*
00189   lookup an entry in the prefix cache. Return NULL if not found.
00190 */
00191 static const char *cache_lookup(unsigned int hash)
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 }
00202 
00203 
00204 /* 
00205    determine if a string is possibly in a mangled format, ignoring
00206    case 
00207 
00208    In this algorithm, mangled names use only pure ascii characters (no
00209    multi-byte) so we can avoid doing a UCS2 conversion 
00210  */
00211 static BOOL is_mangled_component(const char *name, size_t len)
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 }
00257 
00258 
00259 
00260 /* 
00261    determine if a string is possibly in a mangled format, ignoring
00262    case 
00263 
00264    In this algorithm, mangled names use only pure ascii characters (no
00265    multi-byte) so we can avoid doing a UCS2 conversion 
00266 
00267    NOTE! This interface must be able to handle a path with unix
00268    directory separators. It should return true if any component is
00269    mangled
00270  */
00271 static BOOL is_mangled(const char *name, const struct share_params *parm)
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 }
00287 
00288 
00289 /* 
00290    see if a filename is an allowable 8.3 name.
00291 
00292    we are only going to allow ascii characters in 8.3 names, as this
00293    simplifies things greatly (it means that we know the string won't
00294    get larger when converted from UNIX to DOS formats)
00295 */
00296 static BOOL is_8_3(const char *name, BOOL check_case, BOOL allow_wildcards, const struct share_params *p)
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 }
00356 
00357 
00358 /*
00359   reset the mangling cache on a smb.conf reload. This only really makes sense for
00360   mangling backends that have parameters in smb.conf, and as this backend doesn't
00361   this is a NULL operation
00362 */
00363 static void mangle_reset(void)
00364 {
00365         /* noop */
00366 }
00367 
00368 
00369 /*
00370   try to find a 8.3 name in the cache, and if found then
00371   replace the string with the original long name. 
00372 */
00373 static BOOL check_cache(char *name, size_t maxlen, const struct share_params *p)
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 }
00419 
00420 
00421 /*
00422   look for a DOS reserved name
00423 */
00424 static BOOL is_reserved_name(const char *name)
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 }
00444 
00445 /*
00446  See if a filename is a legal long filename.
00447  A filename ending in a '.' is not legal unless it's "." or "..". JRA.
00448  A filename ending in ' ' is not legal either. See bug id #2769.
00449 */
00450 
00451 static BOOL is_legal_name(const char *name)
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 }
00501 
00502 /*
00503   the main forward mapping function, which converts a long filename to 
00504   a 8.3 name
00505 
00506   if need83 is not set then we only do the mangling if the name is illegal
00507   as a long name
00508 
00509   if cache83 is not set then we don't cache the result
00510 
00511   the name parameter must be able to hold 13 bytes
00512 */
00513 static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case, const struct share_params *p)
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 }
00624 
00625 
00626 /* initialise the flags table 
00627 
00628   we allow only a very restricted set of characters as 'ascii' in this
00629   mangling backend. This isn't a significant problem as modern clients
00630   use the 'long' filenames anyway, and those don't have these
00631   restrictions. 
00632 */
00633 static void init_tables(void)
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 }
00690 
00691 /*
00692   the following provides the abstraction layer to make it easier
00693   to drop in an alternative mangling implementation */
00694 static struct mangle_fns mangle_fns = {
00695         mangle_reset,
00696         is_mangled,
00697         is_8_3,
00698         check_cache,
00699         name_map
00700 };
00701 
00702 /* return the methods for this mangling implementation */
00703 struct mangle_fns *mangle_hash2_init(void)
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 }
00723 
00724 static void posix_mangle_reset(void)
00725 {;}
00726 
00727 static BOOL posix_is_mangled(const char *s, const struct share_params *p)
00728 {
00729         return False;
00730 }
00731 
00732 static BOOL posix_is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards, const struct share_params *p)
00733 {
00734         return False;
00735 }
00736 
00737 static BOOL posix_check_cache( char *s, size_t maxlen, const struct share_params *p )
00738 {
00739         return False;
00740 }
00741 
00742 static void posix_name_map(char *OutName, BOOL need83, BOOL cache83, int default_case, const struct share_params *p)
00743 {
00744         if (need83) {
00745                 memset(OutName, '\0', 13);
00746         }
00747 }
00748 
00749 /* POSIX paths backend - no mangle. */
00750 static struct mangle_fns posix_mangle_fns = {
00751         posix_mangle_reset,
00752         posix_is_mangled,
00753         posix_is_8_3,
00754         posix_check_cache,
00755         posix_name_map
00756 };
00757 
00758 struct mangle_fns *posix_mangle_init(void)
00759 {
00760         return &posix_mangle_fns;
00761 }

Sambaに対してSat Aug 29 21:23:24 2009に生成されました。  doxygen 1.4.7