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