You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
233 lines
6.6 KiB
233 lines
6.6 KiB
autofs-5.0.999999999 - amd lookup add selector handling functions |
|
|
|
From: Ian Kent <raven@themaw.net> |
|
|
|
|
|
--- |
|
include/parse_subs.h | 77 +++++++++++++++++++++++++++++++++ |
|
lib/parse_subs.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++ |
|
2 files changed, 194 insertions(+) |
|
|
|
diff --git a/include/parse_subs.h b/include/parse_subs.h |
|
index 675411d..a416c59 100644 |
|
--- a/include/parse_subs.h |
|
+++ b/include/parse_subs.h |
|
@@ -25,6 +25,83 @@ |
|
#define PROXIMITY_OTHER 0x0008 |
|
#define PROXIMITY_UNSUPPORTED 0x0010 |
|
|
|
+#define SEL_ARCH 0x00000001 |
|
+#define SEL_KARCH 0x00000002 |
|
+#define SEL_OS 0x00000004 |
|
+#define SEL_OSVER 0x00000008 |
|
+#define SEL_FULL_OS 0x00000010 |
|
+#define SEL_VENDOR 0x00000020 |
|
+#define SEL_HOST 0x00000040 |
|
+#define SEL_HOSTD 0x00000080 |
|
+#define SEL_XHOST 0x00000100 |
|
+#define SEL_DOMAIN 0x00000200 |
|
+#define SEL_BYTE 0x00000400 |
|
+#define SEL_CLUSTER 0x00000800 |
|
+#define SEL_NETGRP 0x00001000 |
|
+#define SEL_NETGRPD 0x00002000 |
|
+#define SEL_IN_NETWORK 0x00004000 |
|
+#define SEL_UID 0x00008000 |
|
+#define SEL_GID 0x00010000 |
|
+#define SEL_KEY 0x00020000 |
|
+#define SEL_MAP 0x00040000 |
|
+#define SEL_PATH 0x00080000 |
|
+#define SEL_EXISTS 0x00100000 |
|
+#define SEL_AUTODIR 0x00200000 |
|
+#define SEL_DOLLAR 0x00400000 |
|
+#define SEL_TRUE 0x00800000 |
|
+#define SEL_FALSE 0x01000000 |
|
+ |
|
+#define SEL_COMP_NONE 0x0000 |
|
+#define SEL_COMP_EQUAL 0x0001 |
|
+#define SEL_COMP_NOTEQUAL 0x0002 |
|
+#define SEL_COMP_NOT 0x0004 |
|
+ |
|
+#define SEL_FLAG_MACRO 0x0001 |
|
+#define SEL_FLAG_FUNC1 0x0002 |
|
+#define SEL_FLAG_FUNC2 0x0004 |
|
+#define SEL_FLAG_STR 0x0100 |
|
+#define SEL_FLAG_NUM 0x0200 |
|
+#define SEL_FLAG_BOOL 0x0400 |
|
+ |
|
+#define SEL_FLAGS_TYPE_MASK 0x00FF |
|
+#define SEL_FLAGS_VALUE_MASK 0xFF00 |
|
+#define SEL_FREE_VALUE_MASK (SEL_FLAG_MACRO|SEL_FLAG_STR|SEL_FLAG_NUM) |
|
+#define SEL_FREE_ARG1_MASK (SEL_FLAG_FUNC1) |
|
+#define SEL_FREE_ARG2_MASK (SEL_FLAG_FUNC2) |
|
+ |
|
+struct type_compare { |
|
+ char *value; |
|
+}; |
|
+ |
|
+struct type_function { |
|
+ char *arg1; |
|
+ char *arg2; |
|
+}; |
|
+ |
|
+struct sel { |
|
+ unsigned long selector; |
|
+ const char *name; |
|
+ unsigned int flags; |
|
+ struct sel *next; |
|
+}; |
|
+ |
|
+struct selector { |
|
+ struct sel *sel; |
|
+ unsigned int compare; |
|
+ |
|
+ union { |
|
+ struct type_compare comp; |
|
+ struct type_function func; |
|
+ }; |
|
+ |
|
+ struct selector *next; |
|
+}; |
|
+ |
|
+void sel_hash_init(void); |
|
+struct sel *sel_lookup(const char *); |
|
+struct selector *get_selector(char *); |
|
+void free_selector(struct selector *); |
|
+ |
|
struct mapent; |
|
|
|
struct map_type_info { |
|
diff --git a/lib/parse_subs.c b/lib/parse_subs.c |
|
index 279f40e..f485a4c 100644 |
|
--- a/lib/parse_subs.c |
|
+++ b/lib/parse_subs.c |
|
@@ -45,6 +45,44 @@ static int volatile ifc_last_len = 0; |
|
#define EXPAND_LEADING_DOT 0x0004 |
|
#define EXPAND_TRAILING_DOT 0x0008 |
|
|
|
+#define SELECTOR_HASH_SIZE 20 |
|
+ |
|
+static struct sel sel_table[] = { |
|
+ { SEL_ARCH, "arch", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, |
|
+ { SEL_KARCH, "karch", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, |
|
+ { SEL_OS, "os", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, |
|
+ { SEL_OSVER, "osver", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, |
|
+ { SEL_FULL_OS, "full_os", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, |
|
+ { SEL_VENDOR, "vendor", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, |
|
+ { SEL_HOST, "host", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, |
|
+ { SEL_HOSTD, "hostd", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, |
|
+ { SEL_XHOST, "xhost", SEL_FLAG_FUNC1|SEL_FLAG_BOOL, NULL }, |
|
+ { SEL_DOMAIN, "domain", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, |
|
+ { SEL_BYTE, "byte", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, |
|
+ { SEL_CLUSTER, "cluster", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, |
|
+ { SEL_NETGRP, "netgrp", SEL_FLAG_FUNC2|SEL_FLAG_BOOL, NULL }, |
|
+ { SEL_NETGRPD, "netgrpd", SEL_FLAG_FUNC2|SEL_FLAG_BOOL, NULL }, |
|
+ { SEL_IN_NETWORK, "in_network", SEL_FLAG_FUNC1|SEL_FLAG_BOOL, NULL }, |
|
+ { SEL_IN_NETWORK, "netnumber", SEL_FLAG_FUNC1|SEL_FLAG_BOOL, NULL }, |
|
+ { SEL_IN_NETWORK, "network", SEL_FLAG_FUNC1|SEL_FLAG_BOOL, NULL }, |
|
+ { SEL_IN_NETWORK, "wire", SEL_FLAG_FUNC1|SEL_FLAG_BOOL, NULL }, |
|
+ { SEL_UID, "uid", SEL_FLAG_MACRO|SEL_FLAG_NUM, NULL }, |
|
+ { SEL_GID, "gid", SEL_FLAG_MACRO|SEL_FLAG_NUM, NULL }, |
|
+ { SEL_KEY, "key", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, |
|
+ { SEL_MAP, "map", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, |
|
+ { SEL_PATH, "path", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, |
|
+ { SEL_EXISTS, "exists", SEL_FLAG_FUNC1|SEL_FLAG_BOOL, NULL }, |
|
+ { SEL_AUTODIR, "autodir", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, |
|
+ { SEL_DOLLAR, "dollar", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, |
|
+ { SEL_TRUE, "true", SEL_FLAG_FUNC1|SEL_FLAG_BOOL, NULL }, |
|
+ { SEL_FALSE, "false", SEL_FLAG_FUNC1|SEL_FLAG_BOOL, NULL }, |
|
+}; |
|
+static unsigned int sel_count = sizeof(sel_table)/sizeof(struct sel); |
|
+ |
|
+static struct sel *sel_hash[SELECTOR_HASH_SIZE]; |
|
+static unsigned int sel_hash_init_done = 0; |
|
+static pthread_mutex_t sel_hash_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
+ |
|
struct types { |
|
char *type; |
|
unsigned int len; |
|
@@ -70,6 +108,85 @@ static struct types format_type[] = { |
|
}; |
|
static unsigned int format_type_count = sizeof(format_type)/sizeof(struct types); |
|
|
|
+static void sel_add(struct sel *sel) |
|
+{ |
|
+ u_int32_t hval = hash(sel->name, SELECTOR_HASH_SIZE); |
|
+ struct sel *old; |
|
+ |
|
+ old = sel_hash[hval]; |
|
+ sel_hash[hval] = sel; |
|
+ sel_hash[hval]->next = old; |
|
+} |
|
+ |
|
+void sel_hash_init(void) |
|
+{ |
|
+ int i; |
|
+ |
|
+ pthread_mutex_lock(&sel_hash_mutex); |
|
+ if (sel_hash_init_done) { |
|
+ pthread_mutex_unlock(&sel_hash_mutex); |
|
+ return; |
|
+ } |
|
+ for (i = 0; i < SELECTOR_HASH_SIZE; i++) |
|
+ sel_hash[i] = NULL; |
|
+ |
|
+ for (i = 0; i < sel_count; i++) |
|
+ sel_add(&sel_table[i]); |
|
+ |
|
+ sel_hash_init_done = 1; |
|
+ pthread_mutex_unlock(&sel_hash_mutex); |
|
+} |
|
+ |
|
+struct sel *sel_lookup(const char *name) |
|
+{ |
|
+ u_int32_t hval = hash(name, SELECTOR_HASH_SIZE); |
|
+ struct sel *sel; |
|
+ |
|
+ pthread_mutex_lock(&sel_hash_mutex); |
|
+ for (sel = sel_hash[hval]; sel != NULL; sel = sel->next) { |
|
+ if (strcmp(name, sel->name) == 0) { |
|
+ pthread_mutex_unlock(&sel_hash_mutex); |
|
+ return sel; |
|
+ } |
|
+ } |
|
+ pthread_mutex_unlock(&sel_hash_mutex); |
|
+ return NULL; |
|
+} |
|
+ |
|
+struct selector *get_selector(char *name) |
|
+{ |
|
+ struct sel *sel; |
|
+ |
|
+ sel = sel_lookup(name); |
|
+ if (sel) { |
|
+ struct selector *new = malloc(sizeof(struct selector)); |
|
+ if (!new) |
|
+ return NULL; |
|
+ memset(new, 0, sizeof(*new)); |
|
+ new->sel = sel; |
|
+ return new; |
|
+ } |
|
+ return NULL; |
|
+} |
|
+ |
|
+void free_selector(struct selector *selector) |
|
+{ |
|
+ struct selector *s = selector; |
|
+ struct selector *next = s; |
|
+ |
|
+ while (s) { |
|
+ next = s->next; |
|
+ if (s->sel->flags & SEL_FREE_VALUE_MASK) |
|
+ free(s->comp.value); |
|
+ if (s->sel->flags & SEL_FREE_ARG1_MASK) |
|
+ free(s->func.arg1); |
|
+ if (s->sel->flags & SEL_FREE_ARG2_MASK) |
|
+ free(s->func.arg2); |
|
+ s = next; |
|
+ } |
|
+ return; |
|
+} |
|
+ |
|
static unsigned int ipv6_mask_cmp(uint32_t *host, uint32_t *iface, uint32_t *mask) |
|
{ |
|
unsigned int ret = 1;
|
|
|