diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2019-01-05 22:06:45 +0100 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2019-01-05 22:06:45 +0100 |
commit | daa68c4b2de9814b8331e7b9079d5fc49bee35c1 (patch) | |
tree | 4f82de8a19abf7b6a0c9e6f511ac23995d9d5851 /src/config-process.c | |
parent | 9e059f898ae1b0528cdde553fd51c661901e283a (diff) | |
download | neco-daa68c4b2de9814b8331e7b9079d5fc49bee35c1.tar neco-daa68c4b2de9814b8331e7b9079d5fc49bee35c1.zip |
Add first parts of interface config handling
Diffstat (limited to 'src/config-process.c')
-rw-r--r-- | src/config-process.c | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/src/config-process.c b/src/config-process.c new file mode 100644 index 0000000..e71b228 --- /dev/null +++ b/src/config-process.c @@ -0,0 +1,135 @@ +#include "config-process.h" +#include "device.h" +#include "keywords.h" +#include "util.h" + +#include <libubox/avl-cmp.h> + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +typedef struct _process_ctx { + struct avl_tree *ret; +} process_ctx_t; + +typedef struct _config_subtype { + struct avl_node node; +} config_subtype_t; + +void config_object_free(config_object_t *obj) { + free_ini_file(obj->data); + free(obj->type); + free(NODE_NAME(obj)); + free(obj); +} + +static bool subtype_supported(const process_ctx_t *ctx, const char *type) { + switch (lookup_keyword(type)) { + case KW_Properties: + case KW_Generate: + case KW_Static: + case KW_DHCP: + case KW_DHCPv6: + return true; + + default: + return avl_find(ctx->ret, type); + } +} + +static config_subtype_t * config_process_subtype(const process_ctx_t *ctx, config_object_t *obj) { + ini_section_t *section; + list_for_each_entry(section, &obj->data->sections, node) { + printf("%s %s %i\n", NODE_NAME(obj), section->name, subtype_supported(ctx, section->name)); + + if (!subtype_supported(ctx, section->name)) + return NULL; + } + + config_subtype_t *ret = calloc(1, sizeof(*ret)); + if (!ret) + return NULL; + + char *name = strdup(NODE_NAME(obj)); + if (!name) { + free(ret); + return NULL; + } + + NODE_NAME(ret) = name; + + return ret; +} + +struct avl_tree * config_process_subtypes(struct avl_tree *sub) { + process_ctx_t ctx; + ctx.ret = calloc(1, sizeof(*ctx.ret)); + if (!ctx.ret) + return NULL; + + avl_init(ctx.ret, avl_strcmp, false, NULL); + + while (true) { + size_t processed = 0; + + config_object_t *obj, *tmp; + avl_for_each_element_safe(sub, obj, node, tmp) { + config_subtype_t *t = config_process_subtype(&ctx, obj); + if (!t) + continue; + + avl_delete(sub, &obj->node); + config_object_free(obj); + + avl_insert(ctx.ret, &t->node); + + processed++; + } + + if (!processed) + break; + } + + return ctx.ret; +} + +static device_t * config_process_device(config_object_t *obj) { + const device_type_t *type = get_device_type(obj->type); + + assert(type != NULL); + + return type->process_config(NODE_NAME(obj), obj->data); +} + +struct avl_tree * config_process_devices(struct avl_tree *devices) { + process_ctx_t ctx; + ctx.ret = calloc(1, sizeof(*ctx.ret)); + if (!ctx.ret) + return NULL; + + avl_init(ctx.ret, avl_strcmp, false, NULL); + + while (true) { + size_t processed = 0; + + config_object_t *obj, *tmp; + avl_for_each_element_safe(devices, obj, node, tmp) { + device_t *device = config_process_device(obj); + if (!device) + continue; + + avl_delete(devices, &obj->node); + config_object_free(obj); + + avl_insert(ctx.ret, &device->node); + + processed++; + } + + if (!processed) + break; + } + + return ctx.ret; +} |