s3: Make char_flags and base_reverse const arrays
[ira/wip.git] / source3 / smbd / mangle_hash2.c
index b9e7d638726f19b016c8eecdcdd0fc26d9611b4c..298f348661dd1e6b158ee582b1f99a72b4a37ed4 100644 (file)
   ===============================================================================
 */
 
+/*
+ * ============================================================================
+ * Whenever you change anything in the FLAG_ or other fields,
+ * re-initialize the tables char_flags and base_reverse by running the
+ * init_tables() routine once and dump its results. To do this, a
+ * single smbd run with
+ *
+ * #define DYNAMIC_MANGLE_TABLES 1
+ *
+ * and debug level 10 should be sufficient.
+ * ============================================================================
+ */
+
 
 #include "includes.h"
 #include "smbd/globals.h"
@@ -93,6 +106,169 @@ static const char * const reserved_names[] =
 { "AUX", "LOCK$", "CON", "COM1", "COM2", "COM3", "COM4",
   "LPT1", "LPT2", "LPT3", "NUL", "PRN", NULL };
 
+#define DYNAMIC_MANGLE_TABLES 0
+
+#if DYNAMIC_MANGLE_TABLES
+
+/* these tables are used to provide fast tests for characters */
+static unsigned char char_flags[256];
+static unsigned char base_reverse[256];
+
+/* 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.
+*/
+static void init_tables(void)
+{
+       int i;
+
+       memset(char_flags, 0, sizeof(char_flags));
+
+       for (i=1;i<128;i++) {
+               if (i <= 0x1f) {
+                       /* Control characters. */
+                       char_flags[i] |= FLAG_ILLEGAL;
+               }
+
+               if ((i >= '0' && i <= '9') ||
+                   (i >= 'a' && i <= 'z') ||
+                   (i >= 'A' && i <= 'Z')) {
+                       char_flags[i] |=  (FLAG_ASCII | FLAG_BASECHAR);
+               }
+               if (strchr("_-$~", i)) {
+                       char_flags[i] |= FLAG_ASCII;
+               }
+
+               if (strchr("*\\/?<>|\":", i)) {
+                       char_flags[i] |= FLAG_ILLEGAL;
+               }
+
+               if (strchr("*?\"<>", i)) {
+                       char_flags[i] |= FLAG_WILDCARD;
+               }
+       }
+
+       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 */
+       for (i=0; reserved_names[i]; i++) {
+               unsigned char c1, c2, c3, c4;
+
+               c1 = (unsigned char)reserved_names[i][0];
+               c2 = (unsigned char)reserved_names[i][1];
+               c3 = (unsigned char)reserved_names[i][2];
+               c4 = (unsigned char)reserved_names[i][3];
+
+               char_flags[c1] |= FLAG_POSSIBLE1;
+               char_flags[c2] |= FLAG_POSSIBLE2;
+               char_flags[c3] |= FLAG_POSSIBLE3;
+               char_flags[c4] |= FLAG_POSSIBLE4;
+               char_flags[tolower_ascii(c1)] |= FLAG_POSSIBLE1;
+               char_flags[tolower_ascii(c2)] |= FLAG_POSSIBLE2;
+               char_flags[tolower_ascii(c3)] |= FLAG_POSSIBLE3;
+               char_flags[tolower_ascii(c4)] |= FLAG_POSSIBLE4;
+
+               char_flags[(unsigned char)'.'] |= FLAG_POSSIBLE4;
+       }
+
+#if 0
+       DEBUG(10, ("char_flags\n"));
+       dump_data(10, char_flags, sizeof(char_flags));
+
+       DEBUG(10, ("base_reverse\n"));
+       dump_data(10, base_reverse, sizeof(base_reverse));
+#endif
+}
+
+#else
+
+/*
+ * These tables were initialized by a single run of the above
+ * init_tables() routine, dumping the tables and a simple emacs macro.
+ *
+ * Technically we could leave out the 0's at the end of the array
+ * initializers, but I'll leave it in: less surprise.
+ */
+
+static uint8_t char_flags[256] = {
+       0x80, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+       0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+       0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+       0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+       0x00, 0x00, 0x0C, 0x00, 0x02, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x0C, 0x00, 0x00, 0x02, 0x80, 0x04,
+       0x03, 0x83, 0x83, 0x83, 0x83, 0x03, 0x03, 0x03,
+       0x03, 0x03, 0x04, 0x00, 0x0C, 0x00, 0x0C, 0x0C,
+       0x00, 0x13, 0x03, 0x53, 0x03, 0x03, 0x03, 0x03,
+       0x03, 0x03, 0x03, 0x83, 0x53, 0x43, 0x53, 0x23,
+       0x33, 0x03, 0x23, 0x03, 0x43, 0x23, 0x03, 0x03,
+       0x43, 0x03, 0x03, 0x00, 0x04, 0x00, 0x00, 0x02,
+       0x00, 0x13, 0x03, 0x53, 0x03, 0x03, 0x03, 0x03,
+       0x03, 0x03, 0x03, 0x83, 0x53, 0x43, 0x53, 0x23,
+       0x33, 0x03, 0x23, 0x03, 0x43, 0x23, 0x03, 0x03,
+       0x43, 0x03, 0x03, 0x00, 0x04, 0x00, 0x02, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static uint8_t base_reverse[256] = {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+       0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
+       0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+       0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
+       0x21, 0x22, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+#endif
+
 /* 
    hash a string of the specified length. The string does not need to be
    null terminated 
@@ -615,71 +791,6 @@ static bool hash2_name_to_8_3(const char *name,
        return True;
 }
 
-/* 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.
-*/
-static void init_tables(void)
-{
-       int i;
-
-       memset(char_flags, 0, sizeof(char_flags));
-
-       for (i=1;i<128;i++) {
-               if (i <= 0x1f) {
-                       /* Control characters. */
-                       char_flags[i] |= FLAG_ILLEGAL;
-               }
-
-               if ((i >= '0' && i <= '9') ||
-                   (i >= 'a' && i <= 'z') ||
-                   (i >= 'A' && i <= 'Z')) {
-                       char_flags[i] |=  (FLAG_ASCII | FLAG_BASECHAR);
-               }
-               if (strchr("_-$~", i)) {
-                       char_flags[i] |= FLAG_ASCII;
-               }
-
-               if (strchr("*\\/?<>|\":", i)) {
-                       char_flags[i] |= FLAG_ILLEGAL;
-               }
-
-               if (strchr("*?\"<>", i)) {
-                       char_flags[i] |= FLAG_WILDCARD;
-               }
-       }
-
-       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 */
-       for (i=0; reserved_names[i]; i++) {
-               unsigned char c1, c2, c3, c4;
-
-               c1 = (unsigned char)reserved_names[i][0];
-               c2 = (unsigned char)reserved_names[i][1];
-               c3 = (unsigned char)reserved_names[i][2];
-               c4 = (unsigned char)reserved_names[i][3];
-
-               char_flags[c1] |= FLAG_POSSIBLE1;
-               char_flags[c2] |= FLAG_POSSIBLE2;
-               char_flags[c3] |= FLAG_POSSIBLE3;
-               char_flags[c4] |= FLAG_POSSIBLE4;
-               char_flags[tolower_ascii(c1)] |= FLAG_POSSIBLE1;
-               char_flags[tolower_ascii(c2)] |= FLAG_POSSIBLE2;
-               char_flags[tolower_ascii(c3)] |= FLAG_POSSIBLE3;
-               char_flags[tolower_ascii(c4)] |= FLAG_POSSIBLE4;
-
-               char_flags[(unsigned char)'.'] |= FLAG_POSSIBLE4;
-       }
-}
-
 /*
   the following provides the abstraction layer to make it easier
   to drop in an alternative mangling implementation */
@@ -704,7 +815,9 @@ const struct mangle_fns *mangle_hash2_init(void)
                mangle_prefix = 1;
        }
 
+#if DYNAMIC_MANGLE_TABLES
        init_tables();
+#endif
        mangle_reset();
 
        return &mangle_hash2_fns;