diff options
Diffstat (limited to 'src/config-load.c')
-rw-r--r-- | src/config-load.c | 100 |
1 files changed, 42 insertions, 58 deletions
diff --git a/src/config-load.c b/src/config-load.c index 28b5953..92abca0 100644 --- a/src/config-load.c +++ b/src/config-load.c @@ -1,10 +1,11 @@ #include "config-load.h" -#include "config-ini.h" -#include "types.h" +#include "config-process.h" +#include "device.h" +#include "util.h" -#include <libubox/avl.h> #include <libubox/avl-cmp.h> +#include <sys/stat.h> #include <sys/types.h> #include <dirent.h> #include <errno.h> @@ -13,22 +14,9 @@ #include <string.h> #include <unistd.h> -typedef enum { - LOAD_TYPE_INTERFACE, - LOAD_TYPE_SUBCONFIG, - LOAD_TYPE_GENERATOR, - LOAD_TYPE_DEVICE, - N_LOAD_TYPES, -} load_type_t; - -typedef struct { - struct avl_node node; - char *type; - ini_file_t *data; -} load_object_t; - -typedef struct { - struct avl_tree objects[N_LOAD_TYPES]; +typedef struct _load_ctx { + struct avl_tree subtypes; + struct avl_tree devices; } load_ctx_t; static const char * extname(const char *filename) { @@ -36,29 +24,24 @@ static const char * extname(const char *filename) { return dot ? (dot+1) : NULL; } -static void free_object(load_object_t *obj) { - free_ini_file(obj->data); - free(obj->type); - free(NODE_NAME(obj)); - free(obj); +static bool isfile(int fd) { + struct stat buf; + if (fstat(fd, &buf) < 0) + return false; + + return (buf.st_mode & S_IFMT) == S_IFREG; } static bool read_config_file(load_ctx_t *ctx, int dirfd, const char *filename) { const char *ext = extname(filename); - if (!ext) { - errno = EINVAL; - return false; - } + if (!ext) + return true; - load_type_t type; - if (strcmp(ext, "interface") == 0) - type = LOAD_TYPE_INTERFACE; - else if (strcmp(ext, "sub") == 0) - type = LOAD_TYPE_SUBCONFIG; - else if (strcmp(ext, "gen") == 0) - type = LOAD_TYPE_GENERATOR; - else if (strcmp(ext, "bridge") == 0) - type = LOAD_TYPE_DEVICE; + struct avl_tree *target_tree; + if (strcmp(ext, "sub") == 0 || strcmp(ext, "gen") == 0) + target_tree = &ctx->subtypes; + else if (get_device_type(ext)) + target_tree = &ctx->devices; else return true; @@ -66,6 +49,11 @@ static bool read_config_file(load_ctx_t *ctx, int dirfd, const char *filename) { if (fd < 0) return false; + if (!isfile(fd)) { + close(fd); + return true; + } + FILE *f = fdopen(fd, "r"); if (!f) { close(fd); @@ -78,7 +66,7 @@ static bool read_config_file(load_ctx_t *ctx, int dirfd, const char *filename) { if (!data) return false; - load_object_t *obj = calloc(1, sizeof(*obj)); + config_object_t *obj = calloc(1, sizeof(*obj)); if (!obj) { free_ini_file(data); return false; @@ -87,18 +75,18 @@ static bool read_config_file(load_ctx_t *ctx, int dirfd, const char *filename) { char *name = strndup(filename, (ext - filename) - 1); if (!name) { - free_object(obj); + config_object_free(obj); return false; } NODE_NAME(obj) = name; obj->type = strdup(ext); if (!obj->type) { - free_object(obj); + config_object_free(obj); return false; } - avl_insert(&ctx->objects[type], &obj->node); + avl_insert(target_tree, &obj->node); return true; } @@ -111,10 +99,8 @@ static bool read_config_dir(load_ctx_t *ctx, const char *path) { int fd = dirfd(dir); struct dirent *ent; - while ((ent = readdir(dir)) != NULL) { - if (ent->d_type == DT_REG) - read_config_file(ctx, fd, ent->d_name); - } + while ((ent = readdir(dir)) != NULL) + read_config_file(ctx, fd, ent->d_name); closedir(dir); @@ -123,23 +109,21 @@ static bool read_config_dir(load_ctx_t *ctx, const char *path) { bool read_config(const char *path) { load_ctx_t ctx; - for (size_t i = 0; i < N_LOAD_TYPES; i++) - avl_init(&ctx.objects[i], avl_strcmp, true, NULL); + avl_init(&ctx.subtypes, avl_strcmp, true, NULL); + avl_init(&ctx.devices, avl_strcmp, true, NULL); bool ret = read_config_dir(&ctx, path); - for (size_t i = 0; i < N_LOAD_TYPES; i++) { - load_object_t *obj; - avl_for_each_element(&ctx.objects[i], obj, node) { - printf("%s(%u): %s\n", obj->type, (unsigned)i, NODE_NAME(obj)); - } - } + struct avl_tree *subtypes = config_process_subtypes(&ctx.subtypes); + struct avl_tree *devices = config_process_devices(&ctx.devices); - for (size_t i = 0; i < N_LOAD_TYPES; i++) { - load_object_t *obj, *tmp; - avl_for_each_element_safe(&ctx.objects[i], obj, node, tmp) - free_object(obj); - } + free(subtypes); + + device_t *dev, *tmp; + avl_remove_all_elements(devices, dev, node, tmp) + dev->type->free_device(dev); + + free(devices); return ret; } |