libgluonutil: merge domain and site configs
[Matthias Schiffer: rebase and simplify]
This commit is contained in:
parent
a2f45d0d32
commit
146787fa5c
@ -16,7 +16,7 @@ define Package/libgluonutil
|
|||||||
SECTION:=libs
|
SECTION:=libs
|
||||||
CATEGORY:=Libraries
|
CATEGORY:=Libraries
|
||||||
TITLE:=Gluon utility library
|
TITLE:=Gluon utility library
|
||||||
DEPENDS:=+libjson-c
|
DEPENDS:=+libjson-c +libuci
|
||||||
endef
|
endef
|
||||||
|
|
||||||
CMAKE_OPTIONS += \
|
CMAKE_OPTIONS += \
|
||||||
|
@ -6,7 +6,7 @@ set_property(DIRECTORY PROPERTY COMPILE_DEFINITIONS _GNU_SOURCE)
|
|||||||
|
|
||||||
add_library(gluonutil SHARED libgluonutil.c)
|
add_library(gluonutil SHARED libgluonutil.c)
|
||||||
set_property(TARGET gluonutil PROPERTY COMPILE_FLAGS "-Wall -std=c99")
|
set_property(TARGET gluonutil PROPERTY COMPILE_FLAGS "-Wall -std=c99")
|
||||||
target_link_libraries(gluonutil json-c)
|
target_link_libraries(gluonutil json-c uci)
|
||||||
install(TARGETS gluonutil
|
install(TARGETS gluonutil
|
||||||
ARCHIVE DESTINATION lib
|
ARCHIVE DESTINATION lib
|
||||||
LIBRARY DESTINATION lib
|
LIBRARY DESTINATION lib
|
||||||
|
@ -27,11 +27,44 @@
|
|||||||
#include "libgluonutil.h"
|
#include "libgluonutil.h"
|
||||||
|
|
||||||
#include <json-c/json.h>
|
#include <json-c/json.h>
|
||||||
|
#include <uci.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merges two JSON objects
|
||||||
|
*
|
||||||
|
* Both objects are consumed. On conflicts, object b will be preferred.
|
||||||
|
*/
|
||||||
|
static struct json_object * merge_json(struct json_object *a, struct json_object *b) {
|
||||||
|
if (!json_object_is_type(a, json_type_object) || !json_object_is_type(b, json_type_object)) {
|
||||||
|
json_object_put(a);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object *m = json_object_new_object();
|
||||||
|
|
||||||
|
json_object_object_foreach(a, key_a, val_a)
|
||||||
|
json_object_object_add(m, key_a, json_object_get(val_a));
|
||||||
|
json_object_put(a);
|
||||||
|
|
||||||
|
json_object_object_foreach(b, key_b, val_b) {
|
||||||
|
struct json_object *val_m;
|
||||||
|
|
||||||
|
if (json_object_object_get_ex(m, key_b, &val_m))
|
||||||
|
val_m = merge_json(json_object_get(val_m), json_object_get(val_b));
|
||||||
|
else
|
||||||
|
val_m = json_object_get(val_b);
|
||||||
|
|
||||||
|
json_object_object_add(m, key_b, val_m);
|
||||||
|
}
|
||||||
|
json_object_put(b);
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
char * gluonutil_read_line(const char *filename) {
|
char * gluonutil_read_line(const char *filename) {
|
||||||
FILE *f = fopen(filename, "r");
|
FILE *f = fopen(filename, "r");
|
||||||
@ -141,6 +174,75 @@ bool gluonutil_get_node_prefix6(struct in6_addr *prefix) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct json_object * gluonutil_load_site_config(void) {
|
|
||||||
return json_object_from_file("/lib/gluon/site.json");
|
bool gluonutil_has_domains(void) {
|
||||||
|
return (access("/lib/gluon/domains/", F_OK) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * gluonutil_get_domain(void) {
|
||||||
|
if (!gluonutil_has_domains())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
char *ret = NULL;
|
||||||
|
|
||||||
|
struct uci_context *ctx = uci_alloc_context();
|
||||||
|
if (!ctx)
|
||||||
|
goto uci_fail;
|
||||||
|
|
||||||
|
ctx->flags &= ~UCI_FLAG_STRICT;
|
||||||
|
|
||||||
|
struct uci_package *p;
|
||||||
|
if (uci_load(ctx, "gluon", &p))
|
||||||
|
goto uci_fail;
|
||||||
|
|
||||||
|
struct uci_section *s = uci_lookup_section(ctx, p, "core");
|
||||||
|
if (!s)
|
||||||
|
goto uci_fail;
|
||||||
|
|
||||||
|
const char *domain_code = uci_lookup_option_string(ctx, s, "domain");
|
||||||
|
if (!domain_code)
|
||||||
|
goto uci_fail;
|
||||||
|
|
||||||
|
ret = strdup(domain_code);
|
||||||
|
|
||||||
|
uci_fail:
|
||||||
|
if (ctx)
|
||||||
|
uci_free_context(ctx);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct json_object * gluonutil_load_site_config(void) {
|
||||||
|
char *domain_code = NULL;
|
||||||
|
struct json_object *site = NULL, *domain = NULL;
|
||||||
|
|
||||||
|
site = json_object_from_file("/lib/gluon/site.json");
|
||||||
|
if (!site)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!gluonutil_has_domains())
|
||||||
|
return site;
|
||||||
|
|
||||||
|
domain_code = gluonutil_get_domain();
|
||||||
|
if (!domain_code)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
{
|
||||||
|
const char *domain_path_fmt = "/lib/gluon/domains/%s.json";
|
||||||
|
char domain_path[strlen(domain_path_fmt) + strlen(domain_code)];
|
||||||
|
snprintf(domain_path, sizeof(domain_path), domain_path_fmt, domain_code);
|
||||||
|
free(domain_code);
|
||||||
|
|
||||||
|
domain = json_object_from_file(domain_path);
|
||||||
|
}
|
||||||
|
if (!domain)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
return merge_json(site, domain);
|
||||||
|
|
||||||
|
err:
|
||||||
|
json_object_put(site);
|
||||||
|
free(domain_code);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,8 @@ bool gluonutil_get_node_prefix6(struct in6_addr *prefix);
|
|||||||
struct json_object * gluonutil_wrap_string(const char *str);
|
struct json_object * gluonutil_wrap_string(const char *str);
|
||||||
struct json_object * gluonutil_wrap_and_free_string(char *str);
|
struct json_object * gluonutil_wrap_and_free_string(char *str);
|
||||||
|
|
||||||
|
bool gluonutil_has_domains(void);
|
||||||
|
char * gluonutil_get_domain(void);
|
||||||
struct json_object * gluonutil_load_site_config(void);
|
struct json_object * gluonutil_load_site_config(void);
|
||||||
|
|
||||||
#endif /* _LIBGLUON_LIBGLUON_H_ */
|
#endif /* _LIBGLUON_LIBGLUON_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user