summaryrefslogtreecommitdiffstats
path: root/src/config-load.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/config-load.c')
-rw-r--r--src/config-load.c100
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;
}