diff --git a/RELNOTES b/RELNOTES index ef8cf5a2..e663d6df 100644 --- a/RELNOTES +++ b/RELNOTES @@ -76,6 +76,10 @@ suggested fixes to . the DHCPv6 client configuration. 'send dhcp6.oro' is no longer necessary. +- Bug fixed where configuration file parsing did not work with + zero-length options; this made it impossible to set the + rapid-commit option. + Changes since 4.0.0a1 - Bug in octal parsing fixed. Thanks to Bernd Fuhrmann for the report diff --git a/common/parse.c b/common/parse.c index 4d180c11..d9f01a8a 100644 --- a/common/parse.c +++ b/common/parse.c @@ -4825,7 +4825,7 @@ struct option *option; * not an array of pairs of IP addresses, or something like * that. */ - int uniform = option -> format [1] == 'A'; + int uniform = 0; and_again: /* Set fmt to start of format for 'A' and one char back @@ -4837,9 +4837,10 @@ struct option *option; fmt = option->format; /* 'a' means always uniform */ - uniform |= (fmt [1] == 'a'); + if ((fmt[0] != '\0') && (tolower(fmt[1]) == 'a')) + uniform = 1; - for ( ; *fmt; fmt++) { + do { if ((*fmt == 'A') || (*fmt == 'a')) break; if (*fmt == 'o') @@ -4860,7 +4861,12 @@ struct option *option; } if (tmp) expression_dereference (&tmp, MDL); - } + + if (*fmt != '\0') + fmt++; + + } while (*fmt != '\0'); + if ((*fmt == 'A') || (*fmt == 'a')) { token = peek_token (&val, (unsigned *)0, cfile); /* Comma means: continue with next element in array */ @@ -4904,13 +4910,16 @@ int parse_option_statement (result, cfile, lookups, option, op) int lose; token = peek_token (&val, (unsigned *)0, cfile); - if (token == SEMI) { + if ((token == SEMI) && (option->format[0] != '\0')) { /* Eat the semicolon... */ + /* + * XXXSK: I'm not sure why we should ever get here, but we + * do during our startup. This confuses things if + * we are parsing a zero-length option, so don't + * eat the semicolon token in that case. + */ token = next_token (&val, (unsigned *)0, cfile); - goto done; - } - - if (token == EQUAL) { + } else if (token == EQUAL) { /* Eat the equals sign. */ token = next_token (&val, (unsigned *)0, cfile); @@ -4926,16 +4935,11 @@ int parse_option_statement (result, cfile, lookups, option, op) } return 0; } - - /* We got a valid expression, so use it. */ - goto done; + } else { + if (! parse_option_data(&expr, cfile, lookups, option)) + return 0; } - /* Parse the option data... */ - if (! parse_option_data(&expr, cfile, lookups, option)) - return 0; - - done: if (!parse_semi (cfile)) return 0; if (!executable_statement_allocate (result, MDL)) @@ -5192,6 +5196,17 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups) return 0; break; + case '\0': /* Zero-length option. */ + buf[0] = '\0'; + if (!make_const_data(&t, /* expression */ + buf, /* buffer */ + 0, /* length */ + 0, /* terminated */ + 1, /* allocate */ + MDL)) + return 0; + break; + default: parse_warn (cfile, "Bad format %c in parse_option_token.", **fmt);