From aba140a9770f3527973565489e97ee1e0445b93c Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Thu, 20 Aug 2020 04:04:34 -0600 Subject: [PATCH] interface-file: use bsearch to find parser functions --- libifupdown/interface-file.c | 292 ++++++++++++++++++++--------------- 1 file changed, 170 insertions(+), 122 deletions(-) diff --git a/libifupdown/interface-file.c b/libifupdown/interface-file.c index f1f18ce..7b2766e 100644 --- a/libifupdown/interface-file.c +++ b/libifupdown/interface-file.c @@ -74,6 +74,25 @@ report_error(const char *filename, size_t lineno, const char *errfmt, ...) fprintf(stderr, "%s:%zu: %s\n", filename, lineno, errbuf); } +static bool +handle_address(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp) +{ + (void) collection; + (void) token; + + char *addr = lif_next_token(&bufp); + + if (cur_iface == NULL) + { + report_error(filename, lineno, "%s '%s' without interface", token, addr); + return false; + } + + lif_interface_address_add(cur_iface, addr); + + return true; +} + static bool handle_auto(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp) { @@ -95,6 +114,127 @@ handle_auto(struct lif_dict *collection, const char *filename, size_t lineno, ch return true; } +static bool +handle_gateway(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp) +{ + (void) collection; + (void) token; + + char *addr = lif_next_token(&bufp); + + if (cur_iface == NULL) + { + report_error(filename, lineno, "%s '%s' without interface", token, addr); + return false; + } + + lif_interface_use_executor(cur_iface, "static"); + lif_dict_add(&cur_iface->vars, token, strdup(addr)); + + return true; +} + +static bool +handle_generic(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp) +{ + (void) collection; + (void) filename; + (void) lineno; + + if (cur_iface == NULL) + return true; + + token = maybe_remap_token(token); + + lif_dict_add(&cur_iface->vars, token, strdup(bufp)); + + /* Check if token looks like - and assume is an addon */ + char *word_end = strchr(token, '-'); + if (word_end != NULL) + { + /* Copy word1 to not mangle *token */ + char *addon = strndup(token, word_end - token); + lif_interface_use_executor(cur_iface, addon); + free(addon); + + /* pass requires as compatibility env vars to appropriate executors (bridge, bond) */ + if (!strcmp(addon, "bridge")) + cur_iface->is_bridge = true; + else if (!strcmp(addon, "bond")) + cur_iface->is_bond = true; + } + + return true; +} + +static bool handle_inherit(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp); + +static bool +handle_iface(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp) +{ + char *ifname = lif_next_token(&bufp); + if (!*ifname) + { + report_error(filename, lineno, "%s without any other tokens", token); + return false; + } + + cur_iface = lif_interface_collection_find(collection, ifname); + if (cur_iface == NULL) + { + report_error(filename, lineno, "could not upsert interface %s", ifname); + return false; + } + + /* in original ifupdown config, we can have "inet loopback" + * or "inet dhcp" or such to designate hints. lets pick up + * those hints here. + */ + token = lif_next_token(&bufp); + while (*token) + { + if (!strcmp(token, "dhcp")) + lif_interface_use_executor(cur_iface, "dhcp"); + else if (!strcmp(token, "ppp")) + lif_interface_use_executor(cur_iface, "ppp"); + else if (!strcmp(token, "inherits")) + { + if (!handle_inherit(collection, filename, lineno, token, bufp)) + return false; + } + + token = lif_next_token(&bufp); + } + + return true; +} + +static bool +handle_inherit(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp) +{ + char *target = lif_next_token(&bufp); + + if (cur_iface == NULL) + { + report_error(filename, lineno, "%s '%s' without interface", token, target); + return false; + } + + if (!*target) + { + report_error(filename, lineno, "%s: unspecified interface"); + return false; + } + + if (!lif_interface_collection_inherit(cur_iface, collection, target)) + { + report_error(filename, lineno, "could not inherit %s", target); + return false; + } + + return true; +} + static bool handle_source(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp) { @@ -117,6 +257,29 @@ handle_source(struct lif_dict *collection, const char *filename, size_t lineno, return lif_interface_file_parse(collection, source_filename); } +static bool +handle_use(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp) +{ + (void) collection; + + char *executor = lif_next_token(&bufp); + + if (cur_iface == NULL) + { + report_error(filename, lineno, "%s '%s' without interface", token, executor); + return false; + } + + /* pass requires as compatibility env vars to appropriate executors (bridge, bond) */ + if (!strcmp(executor, "bridge")) + cur_iface->is_bridge = true; + else if (!strcmp(executor, "bond")) + cur_iface->is_bond = true; + + lif_interface_use_executor(cur_iface, executor); + return true; +} + /* map keywords to parser functions */ struct parser_keyword { const char *token; @@ -124,8 +287,13 @@ struct parser_keyword { }; static const struct parser_keyword keywords[] = { + {"address", handle_address}, {"auto", handle_auto}, + {"gateway", handle_gateway}, + {"iface", handle_iface}, + {"inherit", handle_inherit}, {"source", handle_source}, + {"use", handle_use}, }; static int @@ -164,128 +332,8 @@ lif_interface_file_parse(struct lif_dict *collection, const char *filename) if (!parserkw->handle(collection, filename, lineno, token, bufp)) goto parse_error; } - else if (!strcmp(token, "iface")) - { - char *ifname = lif_next_token(&bufp); - if (!*ifname) - goto parse_error; - - cur_iface = lif_interface_collection_find(collection, ifname); - if (cur_iface == NULL) - goto parse_error; - - /* in original ifupdown config, we can have "inet loopback" - * or "inet dhcp" or such to designate hints. lets pick up - * those hints here. - */ - char *token = lif_next_token(&bufp); - while (*token) - { - if (!strcmp(token, "dhcp")) - lif_interface_use_executor(cur_iface, "dhcp"); - else if (!strcmp(token, "ppp")) - lif_interface_use_executor(cur_iface, "ppp"); - else if (!strcmp(token, "inherits")) - { - token = lif_next_token(&bufp); - - if (!*token) - { - report_error(filename, lineno, "inherits without interface"); - goto parse_error; - } - - if (!lif_interface_collection_inherit(cur_iface, collection, token)) - { - report_error(filename, lineno, "could not inherit %s", token); - goto parse_error; - } - } - - token = lif_next_token(&bufp); - } - } - else if (!strcmp(token, "use")) - { - char *executor = lif_next_token(&bufp); - - if (cur_iface == NULL) - { - report_error(filename, lineno, "use '%s' without interface", executor); - goto parse_error; - } - - /* pass requires as compatibility env vars to appropriate executors (bridge, bond) */ - if (!strcmp(executor, "bridge")) - cur_iface->is_bridge = true; - else if (!strcmp(executor, "bond")) - cur_iface->is_bond = true; - - lif_interface_use_executor(cur_iface, executor); - } - else if (!strcmp(token, "inherit")) - { - token = lif_next_token(&bufp); - - if (!*token) - { - report_error(filename, lineno, "inherits without interface"); - goto parse_error; - } - - if (!lif_interface_collection_inherit(cur_iface, collection, token)) - { - report_error(filename, lineno, "could not inherit %s", token); - goto parse_error; - } - } - else if (!strcmp(token, "address")) - { - char *addr = lif_next_token(&bufp); - - if (cur_iface == NULL) - { - report_error(filename, lineno, "%s: address '%s' without interface", filename, addr); - goto parse_error; - } - - lif_interface_address_add(cur_iface, addr); - } - else if (!strcmp(token, "gateway")) - { - char *addr = lif_next_token(&bufp); - - if (cur_iface == NULL) - { - report_error(filename, lineno, "%s: gateway '%s' without interface", filename, addr); - goto parse_error; - } - - lif_interface_use_executor(cur_iface, "static"); - lif_dict_add(&cur_iface->vars, token, strdup(addr)); - } - else if (cur_iface != NULL) - { - token = maybe_remap_token(token); - - lif_dict_add(&cur_iface->vars, token, strdup(bufp)); - - /* Check if token looks like - and assume is an addon */ - char *word_end = strchr(token, '-'); - if (word_end != NULL) - { - /* Copy word1 to not mangle *token */ - char *addon = strndup(token, word_end - token); - lif_interface_use_executor(cur_iface, addon); - free(addon); - - /* pass requires as compatibility env vars to appropriate executors (bridge, bond) */ - if (!strcmp(addon, "bridge")) - cur_iface->is_bridge = true; - else if (!strcmp(addon, "bond")) - cur_iface->is_bond = true; - } - } + else if (!handle_generic(collection, filename, lineno, token, bufp)) + goto parse_error; } fclose(f);