Blame SOURCES/autofs-5.0.9-amd-lookup-add-merge_options-function.patch

4d476f
autofs-5.0.9 - mad lookup add merge_options() function
4d476f
4d476f
From: Ian Kent <raven@themaw.net>
4d476f
4d476f
4d476f
---
4d476f
 include/parse_subs.h |    1 
4d476f
 lib/parse_subs.c     |  113 ++++++++++++++++++++++++++++++++++++++++++++++++++
4d476f
 2 files changed, 114 insertions(+)
4d476f
4d476f
diff --git a/include/parse_subs.h b/include/parse_subs.h
4d476f
index c0da5ae..e57cf4a 100644
4d476f
--- a/include/parse_subs.h
4d476f
+++ b/include/parse_subs.h
4d476f
@@ -41,6 +41,7 @@ int strmcmp(const char *, const char *, int);
4d476f
 char *dequote(const char *, int, unsigned int);
4d476f
 int span_space(const char *, unsigned int);
4d476f
 char *sanitize_path(const char *, int, unsigned int, unsigned int);
4d476f
+char *merge_options(const char *, const char *);
4d476f
 void free_map_type_info(struct map_type_info *);
4d476f
 struct map_type_info *parse_map_type_info(const char *);
4d476f
 
4d476f
diff --git a/lib/parse_subs.c b/lib/parse_subs.c
4d476f
index b77d890..99075b1 100644
4d476f
--- a/lib/parse_subs.c
4d476f
+++ b/lib/parse_subs.c
4d476f
@@ -23,6 +23,9 @@
4d476f
 #include <net/if.h>
4d476f
 #include "automount.h"
4d476f
 
4d476f
+#define MAX_OPTIONS_LEN		256
4d476f
+#define MAX_OPTION_LEN		40
4d476f
+
4d476f
 #define MAX_NETWORK_LEN		255
4d476f
 
4d476f
 #define MAX_IFC_BUF		2048
4d476f
@@ -523,6 +526,116 @@ char *sanitize_path(const char *path, int origlen, unsigned int type, unsigned i
4d476f
 	return s_path;
4d476f
 }
4d476f
 
4d476f
+static char *hasopt(const char *str, const char *opt)
4d476f
+{
4d476f
+	const size_t optlen = strlen(opt);
4d476f
+	char *rest = (char *) str, *p;
4d476f
+
4d476f
+	while ((p = strstr(rest, opt)) != NULL) {
4d476f
+		if ((p == rest || p[-1] == ',') &&
4d476f
+		    (p[optlen] == '\0' || p[optlen] == '=' ||
4d476f
+		     p[optlen] == ','))
4d476f
+			return p;
4d476f
+
4d476f
+		rest = strchr (p, ',');
4d476f
+		if (rest == NULL)
4d476f
+			break;
4d476f
+		++rest;
4d476f
+	}
4d476f
+
4d476f
+	return NULL;
4d476f
+}
4d476f
+
4d476f
+char *merge_options(const char *opt1, const char *opt2)
4d476f
+{
4d476f
+	char str[MAX_OPTIONS_LEN];
4d476f
+	char result[MAX_OPTIONS_LEN];
4d476f
+	char neg[MAX_OPTION_LEN];
4d476f
+	char *tok, *ptr = NULL;
4d476f
+	size_t len;
4d476f
+
4d476f
+	if (!opt1 && !opt2)
4d476f
+		return NULL;
4d476f
+
4d476f
+	if (!opt2)
4d476f
+		return strdup(opt1);
4d476f
+
4d476f
+	if (!opt1)
4d476f
+		return strdup(opt2);
4d476f
+
4d476f
+	if (!strcmp(opt1, opt2))
4d476f
+		return strdup(opt1);
4d476f
+
4d476f
+	memset(result, 0, sizeof(result));
4d476f
+	strcpy(str, opt1);
4d476f
+
4d476f
+	tok = strtok_r(str, ",", &ptr);
4d476f
+	while (tok) {
4d476f
+		const char *this = (const char *) tok;
4d476f
+		char *eq = strchr(this, '=');
4d476f
+		if (eq) {
4d476f
+			*eq = '\0';
4d476f
+			if (!hasopt(opt2, this)) {
4d476f
+				*eq = '=';
4d476f
+				if (!*result)
4d476f
+					strcpy(result, this);
4d476f
+				else
4d476f
+					strcat(result, this);
4d476f
+				strcat(result, ",");
4d476f
+				goto next;
4d476f
+			}
4d476f
+		}
4d476f
+
4d476f
+		if (!strcmp(this, "rw") && hasopt(opt2, "ro"))
4d476f
+			goto next;
4d476f
+		if (!strcmp(this, "ro") && hasopt(opt2, "rw"))
4d476f
+			goto next;
4d476f
+		if (!strcmp(this, "bg") && hasopt(opt2, "fg"))
4d476f
+			goto next;
4d476f
+		if (!strcmp(this, "fg") && hasopt(opt2, "bg"))
4d476f
+			goto next;
4d476f
+		if (!strcmp(this, "bg") && hasopt(opt2, "fg"))
4d476f
+			goto next;
4d476f
+		if (!strcmp(this, "soft") && hasopt(opt2, "hard"))
4d476f
+			goto next;
4d476f
+		if (!strcmp(this, "hard") && hasopt(opt2, "soft"))
4d476f
+			goto next;
4d476f
+
4d476f
+		if (!strncmp(this, "no", 2)) {
4d476f
+			strcpy(neg, this + 2);
4d476f
+			if (hasopt(opt2, neg))
4d476f
+				goto next;
4d476f
+		} else {
4d476f
+			strcpy(neg, "no");
4d476f
+			strcat(neg, this);
4d476f
+			if (hasopt(opt2, neg))
4d476f
+				goto next;
4d476f
+		}
4d476f
+
4d476f
+		if (hasopt(opt2, tok))
4d476f
+			goto next;
4d476f
+
4d476f
+		if (!*result)
4d476f
+			strcpy(result, this);
4d476f
+		else
4d476f
+			strcat(result, this);
4d476f
+		strcat(result, ",");
4d476f
+next:
4d476f
+		tok = strtok_r(NULL, ",", &ptr);
4d476f
+	}
4d476f
+
4d476f
+	if (!*result)
4d476f
+		strcpy(result, opt2);
4d476f
+	else
4d476f
+		strcat(result, opt2);
4d476f
+
4d476f
+	len = strlen(result);
4d476f
+	if (len && result[len - 1] == ',')
4d476f
+		result[len - 1] = '\0';
4d476f
+
4d476f
+	return strdup(result);
4d476f
+}
4d476f
+
4d476f
 void free_map_type_info(struct map_type_info *info)
4d476f
 {
4d476f
 	if (info->type)