interface-file: simplify state management a bit
This commit is contained in:
parent
d76c2df460
commit
3bcfe91e84
2 changed files with 56 additions and 46 deletions
|
@ -121,7 +121,7 @@ maybe_remap_token(const char *token)
|
|||
static struct lif_interface *cur_iface = NULL;
|
||||
|
||||
static void
|
||||
report_error(const char *filename, size_t lineno, const char *errfmt, ...)
|
||||
report_error(struct lif_interface_file_parse_state *state, const char *errfmt, ...)
|
||||
{
|
||||
char errbuf[4096];
|
||||
|
||||
|
@ -130,20 +130,19 @@ report_error(const char *filename, size_t lineno, const char *errfmt, ...)
|
|||
vsnprintf(errbuf, sizeof errbuf, errfmt, va);
|
||||
va_end(va);
|
||||
|
||||
fprintf(stderr, "%s:%zu: %s\n", filename, lineno, errbuf);
|
||||
fprintf(stderr, "%s:%zu: %s\n", state->cur_filename, state->cur_lineno, errbuf);
|
||||
}
|
||||
|
||||
static bool
|
||||
handle_address(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp)
|
||||
handle_address(struct lif_interface_file_parse_state *state, 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);
|
||||
report_error(state, "%s '%s' without interface", token, addr);
|
||||
/* Ignore this address, but don't fail hard */
|
||||
return true;
|
||||
}
|
||||
|
@ -154,21 +153,19 @@ handle_address(struct lif_dict *collection, const char *filename, size_t lineno,
|
|||
}
|
||||
|
||||
static bool
|
||||
handle_auto(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp)
|
||||
handle_auto(struct lif_interface_file_parse_state *state, char *token, char *bufp)
|
||||
{
|
||||
(void) filename;
|
||||
(void) lineno;
|
||||
(void) token;
|
||||
|
||||
char *ifname = lif_next_token(&bufp);
|
||||
if (!*ifname && cur_iface == NULL)
|
||||
{
|
||||
report_error(filename, lineno, "auto without interface");
|
||||
report_error(state, "auto without interface");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_iface = lif_interface_collection_find(collection, ifname);
|
||||
cur_iface = lif_interface_collection_find(state->collection, ifname);
|
||||
if (cur_iface == NULL)
|
||||
return false;
|
||||
}
|
||||
|
@ -180,16 +177,15 @@ handle_auto(struct lif_dict *collection, const char *filename, size_t lineno, ch
|
|||
}
|
||||
|
||||
static bool
|
||||
handle_gateway(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp)
|
||||
handle_gateway(struct lif_interface_file_parse_state *state, 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);
|
||||
report_error(state, "%s '%s' without interface", token, addr);
|
||||
/* Ignore this gateway, but don't fail hard */
|
||||
return true;
|
||||
}
|
||||
|
@ -201,11 +197,9 @@ handle_gateway(struct lif_dict *collection, const char *filename, size_t lineno,
|
|||
}
|
||||
|
||||
static bool
|
||||
handle_generic(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp)
|
||||
handle_generic(struct lif_interface_file_parse_state *state, char *token, char *bufp)
|
||||
{
|
||||
(void) collection;
|
||||
(void) filename;
|
||||
(void) lineno;
|
||||
(void) state;
|
||||
|
||||
if (cur_iface == NULL)
|
||||
return true;
|
||||
|
@ -231,23 +225,23 @@ handle_generic(struct lif_dict *collection, const char *filename, size_t lineno,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool handle_inherit(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp);
|
||||
static bool handle_inherit(struct lif_interface_file_parse_state *state, char *token, char *bufp);
|
||||
|
||||
static bool
|
||||
handle_iface(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp)
|
||||
handle_iface(struct lif_interface_file_parse_state *state, char *token, char *bufp)
|
||||
{
|
||||
char *ifname = lif_next_token(&bufp);
|
||||
if (!*ifname)
|
||||
{
|
||||
report_error(filename, lineno, "%s without any other tokens", token);
|
||||
report_error(state, "%s without any other tokens", token);
|
||||
/* This is broken but not fatal */
|
||||
return true;
|
||||
}
|
||||
|
||||
cur_iface = lif_interface_collection_find(collection, ifname);
|
||||
cur_iface = lif_interface_collection_find(state->collection, ifname);
|
||||
if (cur_iface == NULL)
|
||||
{
|
||||
report_error(filename, lineno, "could not upsert interface %s", ifname);
|
||||
report_error(state, "could not upsert interface %s", ifname);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -273,7 +267,7 @@ handle_iface(struct lif_dict *collection, const char *filename, size_t lineno, c
|
|||
lif_interface_use_executor(cur_iface, "ppp");
|
||||
else if (!strcmp(token, "inherits"))
|
||||
{
|
||||
if (!handle_inherit(collection, filename, lineno, token, bufp))
|
||||
if (!handle_inherit(state, token, bufp))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -284,29 +278,29 @@ handle_iface(struct lif_dict *collection, const char *filename, size_t lineno, c
|
|||
}
|
||||
|
||||
static bool
|
||||
handle_inherit(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp)
|
||||
handle_inherit(struct lif_interface_file_parse_state *state, char *token, char *bufp)
|
||||
{
|
||||
char *target = lif_next_token(&bufp);
|
||||
|
||||
if (cur_iface == NULL)
|
||||
{
|
||||
report_error(filename, lineno, "%s '%s' without interface", token, target);
|
||||
report_error(state, "%s '%s' without interface", token, target);
|
||||
/* This is broken but not fatal */
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!*target)
|
||||
{
|
||||
report_error(filename, lineno, "iface %s: unspecified inherit target", cur_iface->ifname);
|
||||
report_error(state, "iface %s: unspecified inherit target", cur_iface->ifname);
|
||||
/* Mark this interface as errornous but carry on */
|
||||
cur_iface->has_config_error = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct lif_interface *parent = lif_interface_collection_find(collection, target);
|
||||
struct lif_interface *parent = lif_interface_collection_find(state->collection, target);
|
||||
if (parent == NULL)
|
||||
{
|
||||
report_error(filename, lineno, "iface %s: could not inherit from %s: not found",
|
||||
report_error(state, "iface %s: could not inherit from %s: not found",
|
||||
cur_iface->ifname, target);
|
||||
/* Mark this interface as errornous but carry on */
|
||||
cur_iface->has_config_error = true;
|
||||
|
@ -316,7 +310,7 @@ handle_inherit(struct lif_dict *collection, const char *filename, size_t lineno,
|
|||
|
||||
if (!lif_config.allow_any_iface_as_template && !parent->is_template)
|
||||
{
|
||||
report_error(filename, lineno, "iface %s: could not inherit from %ss: inheritence from non-template interface not allowed",
|
||||
report_error(state, "iface %s: could not inherit from %ss: inheritence from non-template interface not allowed",
|
||||
cur_iface->ifname, target);
|
||||
/* Mark this interface as errornous but carry on */
|
||||
cur_iface->has_config_error = true;
|
||||
|
@ -325,7 +319,7 @@ handle_inherit(struct lif_dict *collection, const char *filename, size_t lineno,
|
|||
|
||||
if (!lif_interface_collection_inherit(cur_iface, parent))
|
||||
{
|
||||
report_error(filename, lineno, "iface %s: could not inherit from %s", cur_iface->ifname, target);
|
||||
report_error(state, "iface %s: could not inherit from %s", cur_iface->ifname, target);
|
||||
/* Mark this interface as errornous but carry on */
|
||||
cur_iface->has_config_error = true;
|
||||
return true;
|
||||
|
@ -335,39 +329,37 @@ handle_inherit(struct lif_dict *collection, const char *filename, size_t lineno,
|
|||
}
|
||||
|
||||
static bool
|
||||
handle_source(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp)
|
||||
handle_source(struct lif_interface_file_parse_state *state, char *token, char *bufp)
|
||||
{
|
||||
(void) token;
|
||||
|
||||
char *source_filename = lif_next_token(&bufp);
|
||||
if (!*source_filename)
|
||||
{
|
||||
report_error(filename, lineno, "missing filename to source");
|
||||
report_error(state, "missing filename to source");
|
||||
/* Broken but not fatal */
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!strcmp(filename, source_filename))
|
||||
if (!strcmp(state->cur_filename, source_filename))
|
||||
{
|
||||
report_error(filename, lineno, "attempt to source %s would create infinite loop",
|
||||
report_error(state, "attempt to source %s would create infinite loop",
|
||||
source_filename);
|
||||
/* Broken but not fatal */
|
||||
return true;
|
||||
}
|
||||
|
||||
return lif_interface_file_parse(collection, source_filename);
|
||||
return lif_interface_file_parse(state, source_filename);
|
||||
}
|
||||
|
||||
static bool
|
||||
handle_use(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp)
|
||||
handle_use(struct lif_interface_file_parse_state *state, 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);
|
||||
report_error(state, "%s '%s' without interface", token, executor);
|
||||
/* Broken but not fatal */
|
||||
return true;
|
||||
}
|
||||
|
@ -379,7 +371,7 @@ handle_use(struct lif_dict *collection, const char *filename, size_t lineno, cha
|
|||
/* map keywords to parser functions */
|
||||
struct parser_keyword {
|
||||
const char *token;
|
||||
bool (*handle)(struct lif_dict *collection, const char *filename, size_t lineno, char *token, char *bufp);
|
||||
bool (*handle)(struct lif_interface_file_parse_state *state, char *token, char *bufp);
|
||||
};
|
||||
|
||||
static const struct parser_keyword keywords[] = {
|
||||
|
@ -404,17 +396,22 @@ keyword_cmp(const void *a, const void *b)
|
|||
}
|
||||
|
||||
bool
|
||||
lif_interface_file_parse(struct lif_dict *collection, const char *filename)
|
||||
lif_interface_file_parse(struct lif_interface_file_parse_state *state, const char *filename)
|
||||
{
|
||||
FILE *f = fopen(filename, "r");
|
||||
if (f == NULL)
|
||||
return false;
|
||||
|
||||
const char *old_filename = state->cur_filename;
|
||||
state->cur_filename = filename;
|
||||
|
||||
size_t old_lineno = state->cur_lineno;
|
||||
state->cur_lineno = 0;
|
||||
|
||||
char linebuf[4096];
|
||||
size_t lineno = 0;
|
||||
while (lif_fgetline(linebuf, sizeof linebuf, f) != NULL)
|
||||
{
|
||||
lineno++;
|
||||
state->cur_lineno++;
|
||||
|
||||
char *bufp = linebuf;
|
||||
char *token = lif_next_token(&bufp);
|
||||
|
@ -427,17 +424,21 @@ lif_interface_file_parse(struct lif_dict *collection, const char *filename)
|
|||
|
||||
if (parserkw != NULL)
|
||||
{
|
||||
if (!parserkw->handle(collection, filename, lineno, token, bufp))
|
||||
if (!parserkw->handle(state, token, bufp))
|
||||
goto parse_error;
|
||||
}
|
||||
else if (!handle_generic(collection, filename, lineno, token, bufp))
|
||||
else if (!handle_generic(state, token, bufp))
|
||||
goto parse_error;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
state->cur_filename = old_filename;
|
||||
state->cur_lineno = old_lineno;
|
||||
return true;
|
||||
|
||||
parse_error:
|
||||
fclose(f);
|
||||
state->cur_filename = old_filename;
|
||||
state->cur_lineno = old_lineno;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,16 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include "libifupdown/interface.h"
|
||||
#include "libifupdown/dict.h"
|
||||
|
||||
extern bool lif_interface_file_parse(struct lif_dict *collection, const char *filename);
|
||||
struct lif_interface_file_parse_state {
|
||||
struct lif_interface *cur_iface;
|
||||
struct lif_dict *collection;
|
||||
struct lif_dict *loaded;
|
||||
const char *cur_filename;
|
||||
size_t cur_lineno;
|
||||
};
|
||||
|
||||
extern bool lif_interface_file_parse(struct lif_interface_file_parse_state *state, const char *filename);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue