Merge mangle prefix code.
authorJeremy Allison <jra@samba.org>
Mon, 21 Oct 2002 20:40:23 +0000 (20:40 +0000)
committerJeremy Allison <jra@samba.org>
Mon, 21 Oct 2002 20:40:23 +0000 (20:40 +0000)
Jeremy.
(This used to be commit 83261f43326ae65af498399b5c933dfb20df1df7)

source3/param/loadparm.c
source3/smbd/mangle_hash2.c

index a44cc370ac601bb9eb2d685db9571320ed4c7258..effbb7af682a3c3bdf65b4131e8c2c93efada7da 100644 (file)
@@ -167,6 +167,7 @@ typedef struct
        char *szDeleteShareCommand;
        char *szGuestaccount;
        char *szManglingMethod;
+       int mangle_prefix;
        int max_log_size;
        char *szLogLevel;
        int mangled_stack;
@@ -899,6 +900,7 @@ static struct parm_struct parm_table[] = {
        {"Filename Handling", P_SEP, P_SEPARATOR},
        {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
        {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
+       {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
        
        {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
        {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_SHARE},
@@ -1232,8 +1234,9 @@ static void init_globals(void)
        string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
        string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
 
-       /* use the new 'hash2' method by default */
+       /* use the new 'hash2' method by default, with a prefix of 1 */
        string_set(&Globals.szManglingMethod, "hash2");
+       Globals.mangle_prefix = 1;
 
        string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
 
@@ -1520,6 +1523,7 @@ FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
+FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
 #ifdef WITH_UTMP
 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
index 5adde19eea8230995835e2f1dd6771ee5799ba03..bbc9020eabc78b04fa008fa63fecf012a194b82f 100644 (file)
@@ -87,6 +87,13 @@ static unsigned char char_flags[256];
 
 #define FLAG_CHECK(c, flag) (char_flags[(unsigned char)(c)] & (flag))
 
+/*
+  this determines how many characters are used from the original filename
+  in the 8.3 mangled name. A larger value leads to a weaker hash and more collisions.
+  The largest possible value is 6.
+*/
+static unsigned mangle_prefix;
+
 /* we will use a very simple direct mapped prefix cache. The big
    advantage of this cache structure is speed and low memory usage 
 
@@ -217,16 +224,18 @@ static BOOL is_mangled_component(const char *name)
                }
        }
        
-       /* check first character */
-       if (! FLAG_CHECK(name[0], FLAG_ASCII)) {
-               return False;
+       /* check lead characters */
+       for (i=0;i<mangle_prefix;i++) {
+               if (! FLAG_CHECK(name[i], FLAG_ASCII)) {
+                       return False;
+               }
        }
        
        /* check rest of hash */
        if (! FLAG_CHECK(name[7], FLAG_BASECHAR)) {
                return False;
        }
-       for (i=1;i<6;i++) {
+       for (i=mangle_prefix;i<6;i++) {
                if (! FLAG_CHECK(name[i], FLAG_BASECHAR)) {
                        return False;
                }
@@ -371,7 +380,7 @@ static BOOL check_cache(char *name)
 
        /* we need to extract the hash from the 8.3 name */
        hash = base_reverse[(unsigned char)name[7]];
-       for (multiplier=36, i=5;i>=1;i--) {
+       for (multiplier=36, i=5;i>=mangle_prefix;i--) {
                u32 v = base_reverse[(unsigned char)name[i]];
                hash += multiplier * v;
                multiplier *= 36;
@@ -478,7 +487,7 @@ static BOOL is_legal_name(const char *name)
 static void name_map(char *name, BOOL need83, BOOL cache83)
 {
        char *dot_p;
-       char lead_char;
+       char lead_chars[7];
        char extension[4];
        int extension_length, i;
        int prefix_len;
@@ -516,15 +525,20 @@ static void name_map(char *name, BOOL need83, BOOL cache83)
                if (i == 0 || i == 4) dot_p = NULL;
        }
 
-       /* the leading character in the mangled name is taken from
-          the first character of the name, if it is ascii 
-          otherwise '_' is used
+       /* the leading characters in the mangled name is taken from
+          the first characters of the name, if they are ascii otherwise
+          '_' is used
        */
-       lead_char = name[0];
-       if (! FLAG_CHECK(lead_char, FLAG_ASCII)) {
-               lead_char = '_';
+       for (i=0;i<mangle_prefix && name[i];i++) {
+               lead_chars[i] = name[i];
+               if (! FLAG_CHECK(lead_chars[i], FLAG_ASCII)) {
+                       lead_chars[i] = '_';
+               }
+               lead_chars[i] = toupper(lead_chars[i]);
+       }
+       for (;i<mangle_prefix;i++) {
+               lead_chars[i] = '_';
        }
-       lead_char = toupper(lead_char);
 
        /* the prefix is anything up to the first dot */
        if (dot_p) {
@@ -549,10 +563,12 @@ static void name_map(char *name, BOOL need83, BOOL cache83)
        v = hash = mangle_hash(name, prefix_len);
 
        /* now form the mangled name. */
-       new_name[0] = lead_char;
+       for (i=0;i<mangle_prefix;i++) {
+               new_name[i] = lead_chars[i];
+       }
        new_name[7] = base_forward(v % 36);
        new_name[6] = '~';      
-       for (i=5; i>=1; i--) {
+       for (i=5; i>=mangle_prefix; i--) {
                v = v / 36;
                new_name[i] = base_forward(v % 36);
        }
@@ -594,7 +610,7 @@ static void init_tables(void)
 
        memset(char_flags, 0, sizeof(char_flags));
 
-       for (i=0;i<128;i++) {
+       for (i=1;i<128;i++) {
                if ((i >= '0' && i <= '9') || 
                    (i >= 'a' && i <= 'z') || 
                    (i >= 'A' && i <= 'Z')) {
@@ -656,6 +672,15 @@ static struct mangle_fns mangle_fns = {
 /* return the methods for this mangling implementation */
 struct mangle_fns *mangle_hash2_init(void)
 {
+       /* the mangle prefix can only be in the mange 1 to 6 */
+       mangle_prefix = lp_mangle_prefix();
+       if (mangle_prefix > 6) {
+               mangle_prefix = 6;
+       }
+       if (mangle_prefix < 1) {
+               mangle_prefix = 1;
+       }
+
        init_tables();
        mangle_reset();