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.
234 lines
6.6 KiB
234 lines
6.6 KiB
7 years ago
|
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;
|