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