|
|
1eb31d |
---
|
|
|
1eb31d |
libmultipath/parser.c | 154 ++++++++++++++++++++++++++++++++++++++++----------
|
|
|
1eb31d |
1 file changed, 126 insertions(+), 28 deletions(-)
|
|
|
1eb31d |
|
|
|
1eb31d |
Index: multipath-tools-130222/libmultipath/parser.c
|
|
|
1eb31d |
===================================================================
|
|
|
1eb31d |
--- multipath-tools-130222.orig/libmultipath/parser.c
|
|
|
1eb31d |
+++ multipath-tools-130222/libmultipath/parser.c
|
|
|
1eb31d |
@@ -395,36 +395,57 @@ set_value(vector strvec)
|
|
|
1eb31d |
char *alloc = NULL;
|
|
|
1eb31d |
char *tmp;
|
|
|
1eb31d |
|
|
|
1eb31d |
- if (!str)
|
|
|
1eb31d |
+ if (!str) {
|
|
|
1eb31d |
+ condlog(0, "option '%s' missing value",
|
|
|
1eb31d |
+ (char *)VECTOR_SLOT(strvec, 0));
|
|
|
1eb31d |
return NULL;
|
|
|
1eb31d |
-
|
|
|
1eb31d |
+ }
|
|
|
1eb31d |
size = strlen(str);
|
|
|
1eb31d |
- if (size == 0)
|
|
|
1eb31d |
+ if (size == 0) {
|
|
|
1eb31d |
+ condlog(0, "option '%s' has empty value",
|
|
|
1eb31d |
+ (char *)VECTOR_SLOT(strvec, 0));
|
|
|
1eb31d |
return NULL;
|
|
|
1eb31d |
-
|
|
|
1eb31d |
- if (*str == '"') {
|
|
|
1eb31d |
- for (i = 2; i < VECTOR_SIZE(strvec); i++) {
|
|
|
1eb31d |
- str = VECTOR_SLOT(strvec, i);
|
|
|
1eb31d |
- len += strlen(str);
|
|
|
1eb31d |
- if (!alloc)
|
|
|
1eb31d |
- alloc =
|
|
|
1eb31d |
- (char *) MALLOC(sizeof (char *) *
|
|
|
1eb31d |
- (len + 1));
|
|
|
1eb31d |
- else {
|
|
|
1eb31d |
- alloc =
|
|
|
1eb31d |
- REALLOC(alloc, sizeof (char *) * (len + 1));
|
|
|
1eb31d |
- tmp = VECTOR_SLOT(strvec, i-1);
|
|
|
1eb31d |
- if (alloc && *str != '"' && *tmp != '"')
|
|
|
1eb31d |
- strncat(alloc, " ", 1);
|
|
|
1eb31d |
- }
|
|
|
1eb31d |
-
|
|
|
1eb31d |
- if (alloc && i != VECTOR_SIZE(strvec)-1)
|
|
|
1eb31d |
- strncat(alloc, str, strlen(str));
|
|
|
1eb31d |
- }
|
|
|
1eb31d |
- } else {
|
|
|
1eb31d |
- alloc = MALLOC(sizeof (char *) * (size + 1));
|
|
|
1eb31d |
+ }
|
|
|
1eb31d |
+ if (*str != '"') {
|
|
|
1eb31d |
+ alloc = MALLOC(sizeof (char) * (size + 1));
|
|
|
1eb31d |
if (alloc)
|
|
|
1eb31d |
memcpy(alloc, str, size);
|
|
|
1eb31d |
+ else
|
|
|
1eb31d |
+ condlog(0, "can't allocate memeory for option '%s'",
|
|
|
1eb31d |
+ (char *)VECTOR_SLOT(strvec, 0));
|
|
|
1eb31d |
+ return alloc;
|
|
|
1eb31d |
+ }
|
|
|
1eb31d |
+ /* Even empty quotes counts as a value (An empty string) */
|
|
|
1eb31d |
+ alloc = (char *) MALLOC(sizeof (char));
|
|
|
1eb31d |
+ if (!alloc) {
|
|
|
1eb31d |
+ condlog(0, "can't allocate memeory for option '%s'",
|
|
|
1eb31d |
+ (char *)VECTOR_SLOT(strvec, 0));
|
|
|
1eb31d |
+ return NULL;
|
|
|
1eb31d |
+ }
|
|
|
1eb31d |
+ for (i = 2; i < VECTOR_SIZE(strvec); i++) {
|
|
|
1eb31d |
+ str = VECTOR_SLOT(strvec, i);
|
|
|
1eb31d |
+ if (!str) {
|
|
|
1eb31d |
+ free(alloc);
|
|
|
1eb31d |
+ condlog(0, "parse error for option '%s'",
|
|
|
1eb31d |
+ (char *)VECTOR_SLOT(strvec, 0));
|
|
|
1eb31d |
+ return NULL;
|
|
|
1eb31d |
+ }
|
|
|
1eb31d |
+ if (*str == '"')
|
|
|
1eb31d |
+ break;
|
|
|
1eb31d |
+ tmp = alloc;
|
|
|
1eb31d |
+ /* The first +1 is for the NULL byte. The rest are for the
|
|
|
1eb31d |
+ * spaces between words */
|
|
|
1eb31d |
+ len += strlen(str) + 1;
|
|
|
1eb31d |
+ alloc = REALLOC(alloc, sizeof (char) * len);
|
|
|
1eb31d |
+ if (!alloc) {
|
|
|
1eb31d |
+ FREE(tmp);
|
|
|
1eb31d |
+ condlog(0, "can't allocate memeory for option '%s'",
|
|
|
1eb31d |
+ (char *)VECTOR_SLOT(strvec, 0));
|
|
|
1eb31d |
+ return NULL;
|
|
|
1eb31d |
+ }
|
|
|
1eb31d |
+ if (*alloc != '\0')
|
|
|
1eb31d |
+ strncat(alloc, " ", 1);
|
|
|
1eb31d |
+ strncat(alloc, str, strlen(str));
|
|
|
1eb31d |
}
|
|
|
1eb31d |
return alloc;
|
|
|
1eb31d |
}
|
|
|
1eb31d |
@@ -465,6 +486,74 @@ void free_uniques(vector uniques)
|
|
|
1eb31d |
}
|
|
|
1eb31d |
|
|
|
1eb31d |
int
|
|
|
1eb31d |
+is_sublevel_keyword(char *str)
|
|
|
1eb31d |
+{
|
|
|
1eb31d |
+ return (strcmp(str, "defaults") == 0 || strcmp(str, "blacklist") == 0 ||
|
|
|
1eb31d |
+ strcmp(str, "blacklist_exceptions") == 0 ||
|
|
|
1eb31d |
+ strcmp(str, "devices") == 0 || strcmp(str, "devices") == 0 ||
|
|
|
1eb31d |
+ strcmp(str, "device") == 0 || strcmp(str, "multipaths") == 0 ||
|
|
|
1eb31d |
+ strcmp(str, "multipath") == 0);
|
|
|
1eb31d |
+}
|
|
|
1eb31d |
+
|
|
|
1eb31d |
+int
|
|
|
1eb31d |
+validate_config_strvec(vector strvec)
|
|
|
1eb31d |
+{
|
|
|
1eb31d |
+ char *str;
|
|
|
1eb31d |
+ int i;
|
|
|
1eb31d |
+
|
|
|
1eb31d |
+ str = VECTOR_SLOT(strvec, 0);
|
|
|
1eb31d |
+ if (str == NULL) {
|
|
|
1eb31d |
+ condlog(0, "can't parse option on line %d of config file",
|
|
|
1eb31d |
+ line_nr);
|
|
|
1eb31d |
+ return -1;
|
|
|
1eb31d |
+ }
|
|
|
1eb31d |
+ if (*str == '}') {
|
|
|
1eb31d |
+ if (VECTOR_SIZE(strvec) > 1)
|
|
|
1eb31d |
+ condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 1), line_nr);
|
|
|
1eb31d |
+ return 0;
|
|
|
1eb31d |
+ }
|
|
|
1eb31d |
+ if (*str == '{') {
|
|
|
1eb31d |
+ condlog(0, "invalid keyword '%s' on line %d of config file", str, line_nr);
|
|
|
1eb31d |
+ return -1;
|
|
|
1eb31d |
+ }
|
|
|
1eb31d |
+ if (is_sublevel_keyword(str)) {
|
|
|
1eb31d |
+ str = VECTOR_SLOT(strvec, 1);
|
|
|
1eb31d |
+ if (str == NULL)
|
|
|
1eb31d |
+ condlog(0, "missing '{' on line %d of config file", line_nr);
|
|
|
1eb31d |
+ else if (*str != '{')
|
|
|
1eb31d |
+ condlog(0, "expecting '{' on line %d of config file. found '%s'", line_nr, str);
|
|
|
1eb31d |
+ else if (VECTOR_SIZE(strvec) > 2)
|
|
|
1eb31d |
+ condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 2), line_nr);
|
|
|
1eb31d |
+ return 0;
|
|
|
1eb31d |
+ }
|
|
|
1eb31d |
+ str = VECTOR_SLOT(strvec, 1);
|
|
|
1eb31d |
+ if (str == NULL) {
|
|
|
1eb31d |
+ condlog(0, "missing value for option '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 0), line_nr);
|
|
|
1eb31d |
+ return -1;
|
|
|
1eb31d |
+ }
|
|
|
1eb31d |
+ if (*str != '"') {
|
|
|
1eb31d |
+ if (VECTOR_SIZE(strvec) > 2)
|
|
|
1eb31d |
+ condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 2), line_nr);
|
|
|
1eb31d |
+ return 0;
|
|
|
1eb31d |
+ }
|
|
|
1eb31d |
+ for (i = 2; i < VECTOR_SIZE(strvec); i++) {
|
|
|
1eb31d |
+ str = VECTOR_SLOT(strvec, i);
|
|
|
1eb31d |
+ if (str == NULL) {
|
|
|
1eb31d |
+ condlog(0, "can't parse value on line %d of config file", line_nr);
|
|
|
1eb31d |
+ return -1;
|
|
|
1eb31d |
+ }
|
|
|
1eb31d |
+ if (*str == '"') {
|
|
|
1eb31d |
+ if (VECTOR_SIZE(strvec) > i + 1)
|
|
|
1eb31d |
+ condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, (i + 1)), line_nr);
|
|
|
1eb31d |
+ return 0;
|
|
|
1eb31d |
+ }
|
|
|
1eb31d |
+ }
|
|
|
1eb31d |
+ condlog(0, "missing closing quotes on line %d of config file",
|
|
|
1eb31d |
+ line_nr);
|
|
|
1eb31d |
+ return 0;
|
|
|
1eb31d |
+}
|
|
|
1eb31d |
+
|
|
|
1eb31d |
+int
|
|
|
1eb31d |
process_stream(vector keywords)
|
|
|
1eb31d |
{
|
|
|
1eb31d |
int i;
|
|
|
1eb31d |
@@ -494,11 +583,20 @@ process_stream(vector keywords)
|
|
|
1eb31d |
if (!strvec)
|
|
|
1eb31d |
continue;
|
|
|
1eb31d |
|
|
|
1eb31d |
+ if (validate_config_strvec(strvec) != 0) {
|
|
|
1eb31d |
+ free_strvec(strvec);
|
|
|
1eb31d |
+ continue;
|
|
|
1eb31d |
+ }
|
|
|
1eb31d |
+
|
|
|
1eb31d |
str = VECTOR_SLOT(strvec, 0);
|
|
|
1eb31d |
|
|
|
1eb31d |
- if (!strcmp(str, EOB) && kw_level > 0) {
|
|
|
1eb31d |
- free_strvec(strvec);
|
|
|
1eb31d |
- break;
|
|
|
1eb31d |
+ if (!strcmp(str, EOB)) {
|
|
|
1eb31d |
+ if (kw_level > 0) {
|
|
|
1eb31d |
+ free_strvec(strvec);
|
|
|
1eb31d |
+ break;
|
|
|
1eb31d |
+ }
|
|
|
1eb31d |
+ condlog(0, "unmatched '%s' at line %d of config file",
|
|
|
1eb31d |
+ EOB, line_nr);
|
|
|
1eb31d |
}
|
|
|
1eb31d |
|
|
|
1eb31d |
for (i = 0; i < VECTOR_SIZE(keywords); i++) {
|