r25009: Large patch discussed with Volker. Move unix_convert to a talloc-based
[ira/wip.git] / source3 / smbd / mangle_hash2.c
index c3db112051a86d75270b255c7d27760673528796..73f81fe9aeceb945d2b0214f314287e3e5d87ead 100644 (file)
@@ -368,18 +368,23 @@ static void mangle_reset(void)
 
 /*
   try to find a 8.3 name in the cache, and if found then
-  replace the string with the original long name. 
+  replace the string with the original long name.
 */
-static BOOL check_cache(char *name, size_t maxlen, const struct share_params *p)
+static BOOL lookup_name_from_8_3(TALLOC_CTX *ctx,
+                       const char *name,
+                       char **pp_out, /* talloced on the given context. */
+                       const struct share_params *p)
 {
        unsigned int hash, multiplier;
        unsigned int i;
        const char *prefix;
        char extension[4];
 
+       *pp_out = NULL;
+
        /* make sure that this is a mangled name from this cache */
        if (!is_mangled(name, p)) {
-               M_DEBUG(10,("check_cache: %s -> not mangled\n", name));
+               M_DEBUG(10,("lookup_name_from_8_3: %s -> not mangled\n", name));
                return False;
        }
 
@@ -394,7 +399,8 @@ static BOOL check_cache(char *name, size_t maxlen, const struct share_params *p)
        /* now look in the prefix cache for that hash */
        prefix = cache_lookup(hash);
        if (!prefix) {
-               M_DEBUG(10,("check_cache: %s -> %08X -> not found\n", name, hash));
+               M_DEBUG(10,("lookup_name_from_8_3: %s -> %08X -> not found\n",
+                                       name, hash));
                return False;
        }
 
@@ -407,17 +413,22 @@ static BOOL check_cache(char *name, size_t maxlen, const struct share_params *p)
        }
 
        if (extension[0]) {
-               M_DEBUG(10,("check_cache: %s -> %s.%s\n", name, prefix, extension));
-               slprintf(name, maxlen, "%s.%s", prefix, extension);
+               M_DEBUG(10,("lookup_name_from_8_3: %s -> %s.%s\n",
+                                       name, prefix, extension));
+               *pp_out = talloc_asprintf(ctx, "%s.%s", prefix, extension);
        } else {
-               M_DEBUG(10,("check_cache: %s -> %s\n", name, prefix));
-               safe_strcpy(name, prefix, maxlen);
+               M_DEBUG(10,("lookup_name_from_8_3: %s -> %s\n", name, prefix));
+               *pp_out = talloc_strdup(ctx, prefix);
+       }
+
+       if (!pp_out) {
+               M_DEBUG(0,("talloc_fail"));
+               return False;
        }
 
        return True;
 }
 
-
 /*
   look for a DOS reserved name
 */
@@ -499,18 +510,27 @@ static BOOL is_legal_name(const char *name)
        return True;
 }
 
+static BOOL must_mangle(const char *name,
+                       const struct share_params *p)
+{
+       if (is_reserved_name(name)) {
+               return True;
+       }
+       return !is_legal_name(name);
+}
+
 /*
   the main forward mapping function, which converts a long filename to 
   a 8.3 name
 
-  if need83 is not set then we only do the mangling if the name is illegal
-  as a long name
-
   if cache83 is not set then we don't cache the result
 
-  the name parameter must be able to hold 13 bytes
 */
-static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case, const struct share_params *p)
+static BOOL hash2_name_to_8_3(const char *name,
+                       char new_name[13],
+                       BOOL cache83,
+                       int default_case,
+                       const struct share_params *p)
 {
        char *dot_p;
        char lead_chars[7];
@@ -518,20 +538,14 @@ static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case,
        unsigned int extension_length, i;
        unsigned int prefix_len;
        unsigned int hash, v;
-       char new_name[13];
 
        /* reserved names are handled specially */
        if (!is_reserved_name(name)) {
-               /* if the name is already a valid 8.3 name then we don't need to 
-                  do anything */
-               if (is_8_3(name, False, False, p)) {
-                       return;
-               }
-
-               /* if the caller doesn't strictly need 8.3 then just check for illegal 
-                  filenames */
-               if (!need83 && is_legal_name(name)) {
-                       return;
+               /* if the name is already a valid 8.3 name then we don't need to
+                * change anything */
+               if (is_legal_name(name) && is_8_3(name, False, False, p)) {
+                       safe_strcpy(new_name, name, 12);
+                       return True;
                }
        }
 
@@ -548,7 +562,9 @@ static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case,
                                break;
                        }
                }
-               if (i == 0 || i == 4) dot_p = NULL;
+               if (i == 0 || i == 4) {
+                       dot_p = NULL;
+               }
        }
 
        /* the leading characters in the mangled name is taken from
@@ -580,11 +596,12 @@ static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case,
                for (i=1; extension_length < 3 && dot_p[i]; i++) {
                        char c = dot_p[i];
                        if (FLAG_CHECK(c, FLAG_ASCII)) {
-                               extension[extension_length++] = toupper_ascii(c);
+                               extension[extension_length++] =
+                                       toupper_ascii(c);
                        }
                }
        }
-          
+
        /* find the hash for this prefix */
        v = hash = mangle_hash(name, prefix_len);
 
@@ -593,7 +610,7 @@ static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case,
                new_name[i] = lead_chars[i];
        }
        new_name[7] = base_forward(v % 36);
-       new_name[6] = '~';      
+       new_name[6] = '~';
        for (i=5; i>=mangle_prefix; i--) {
                v = v / 36;
                new_name[i] = base_forward(v % 36);
@@ -613,22 +630,18 @@ static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case,
                cache_insert(name, prefix_len, hash);
        }
 
-       M_DEBUG(10,("name_map: %s -> %08X -> %s (cache=%d)\n", 
+       M_DEBUG(10,("hash2_name_to_8_3: %s -> %08X -> %s (cache=%d)\n",
                   name, hash, new_name, cache83));
 
-       /* and overwrite the old name */
-       fstrcpy(name, new_name);
-
-       /* all done, we've managed to mangle it */
+       return True;
 }
 
-
-/* initialise the flags table 
+/* initialise the flags table
 
   we allow only a very restricted set of characters as 'ascii' in this
   mangling backend. This isn't a significant problem as modern clients
   use the 'long' filenames anyway, and those don't have these
-  restrictions. 
+  restrictions.
 */
 static void init_tables(void)
 {
@@ -642,8 +655,8 @@ static void init_tables(void)
                        char_flags[i] |= FLAG_ILLEGAL;
                }
 
-               if ((i >= '0' && i <= '9') || 
-                   (i >= 'a' && i <= 'z') || 
+               if ((i >= '0' && i <= '9') ||
+                   (i >= 'a' && i <= 'z') ||
                    (i >= 'A' && i <= 'Z')) {
                        char_flags[i] |=  (FLAG_ASCII | FLAG_BASECHAR);
                }
@@ -663,7 +676,7 @@ static void init_tables(void)
        memset(base_reverse, 0, sizeof(base_reverse));
        for (i=0;i<36;i++) {
                base_reverse[(unsigned char)base_forward(i)] = i;
-       }       
+       }
 
        /* fill in the reserved names flags. These are used as a very
           fast filter for finding possible DOS reserved filenames */
@@ -694,9 +707,10 @@ static void init_tables(void)
 static struct mangle_fns mangle_fns = {
        mangle_reset,
        is_mangled,
+       must_mangle,
        is_8_3,
-       check_cache,
-       name_map
+       lookup_name_from_8_3,
+       hash2_name_to_8_3
 };
 
 /* return the methods for this mangling implementation */
@@ -729,30 +743,45 @@ static BOOL posix_is_mangled(const char *s, const struct share_params *p)
        return False;
 }
 
-static BOOL posix_is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards, const struct share_params *p)
+static BOOL posix_must_mangle(const char *s, const struct share_params *p)
 {
        return False;
 }
 
-static BOOL posix_check_cache( char *s, size_t maxlen, 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)
 {
        return False;
 }
 
-static void posix_name_map(char *OutName, BOOL need83, BOOL cache83, int default_case, const struct share_params *p)
+static BOOL posix_lookup_name_from_8_3(TALLOC_CTX *ctx,
+                               const char *in,
+                               char **out, /* talloced on the given context. */
+                               const struct share_params *p)
 {
-       if (need83) {
-               memset(OutName, '\0', 13);
-       }
+       return False;
+}
+
+static BOOL posix_name_to_8_3(const char *in,
+                               char out[13],
+                               BOOL cache83,
+                               int default_case,
+                               const struct share_params *p)
+{
+       memset(out, '\0', 13);
+       return True;
 }
 
 /* POSIX paths backend - no mangle. */
 static struct mangle_fns posix_mangle_fns = {
-        posix_mangle_reset,
-        posix_is_mangled,
-        posix_is_8_3,
-        posix_check_cache,
-        posix_name_map
+       posix_mangle_reset,
+       posix_is_mangled,
+       posix_must_mangle,
+       posix_is_8_3,
+       posix_lookup_name_from_8_3,
+       posix_name_to_8_3
 };
 
 struct mangle_fns *posix_mangle_init(void)