Blame SOURCES/autofs-5.0.9-amd-lookup-add-selector-handling-functions.patch

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