summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2018-07-27 17:38:22 +0200
committerJosé Bollo <jose.bollo@iot.bzh>2018-08-02 15:49:43 +0200
commit5ef271effacb83552f9ea56572c751c2f5a556b6 (patch)
tree3d5f6665bde93633b0eb6c648c9ab46951443526 /src
parente39610f8c9b2e6bbb8a460f7d7ccccbc5161b4ed (diff)
Add ability to provide binding settings
Change-Id: Iab93a26340fa9743a58ca43cd903bbf31c783e5b Signed-off-by: Jose Bollo <jose.bollo@iot.bzh>
Diffstat (limited to 'src')
-rw-r--r--src/afb-config.c150
-rw-r--r--src/afb-export.c61
-rw-r--r--src/afb-export.h2
-rw-r--r--src/afb-hook-flags.c1
-rw-r--r--src/afb-hook.c12
-rw-r--r--src/afb-hook.h6
-rw-r--r--src/afb-trace.c20
-rw-r--r--src/main-afb-daemon.c6
8 files changed, 223 insertions, 35 deletions
diff --git a/src/afb-config.c b/src/afb-config.c
index a791969f..c10b2937 100644
--- a/src/afb-config.c
+++ b/src/afb-config.c
@@ -130,11 +130,13 @@
#define SET_PORT 'p'
#define SET_QUIET 'q'
#define SET_RANDOM_TOKEN 'r'
+#define ADD_SET 's'
#define SET_TOKEN 't'
#define SET_UPLOAD_DIR 'u'
#define GET_VERSION 'V'
#define SET_VERBOSE 'v'
#define SET_WORK_DIR 'w'
+#define DUMP_CONFIG 'Z'
/* structure for defining of options */
struct option_desc {
@@ -213,6 +215,9 @@ static struct option_desc optdefs[] = {
#endif
{SET_CONFIG, 1, "config", "Load options from the given config file"},
+ {DUMP_CONFIG, 0, "dump-config", "Dump the config to stdout and exit"},
+
+ {ADD_SET, 1, "set", "Set parameters ([API]/[KEY]:JSON or {\"API\":{\"KEY\":JSON}}" },
{SET_OUTPUT, 1, "output", "Redirect stdout and stderr to output file (when --daemon)"},
{0, 0, NULL, NULL}
@@ -396,6 +401,30 @@ static void printHelp(FILE * file, const char *name)
name);
}
+static void dump(struct json_object *config, FILE *file, const char *prefix, const char *title)
+{
+ const char *head, *tail;
+
+ if (title)
+ fprintf(file, "%s----BEGIN OF %s-----\n", prefix ?: "", title);
+
+ head = json_object_to_json_string_ext(config, JSON_C_TO_STRING_PRETTY
+ |JSON_C_TO_STRING_SPACED|JSON_C_TO_STRING_NOSLASHESCAPE);
+
+ if (!prefix)
+ fprintf(file, "%s\n", head);
+ else {
+ while(*head) {
+ for (tail = head ; *tail && *tail != '\n' ; tail++);
+ fprintf(file, "%s %.*s\n", prefix, (int)(tail - head), head);
+ head = tail + !!*tail;
+ }
+ }
+
+ if (title)
+ fprintf(file, "%s----END OF %s-----\n", prefix ?: "", title);
+}
+
/**********************************
* json helpers
***********************************/
@@ -539,8 +568,7 @@ static void config_add(struct json_object *config, int optid, struct json_object
{
struct json_object *a;
if (!json_object_object_get_ex(config, name_of_optid(optid), &a)) {
- a = json_object_new_array();
- oomchk(a);
+ a = joomchk(json_object_new_array());
json_object_object_add(config, name_of_optid(optid), a);
}
json_object_array_add(a, val);
@@ -556,6 +584,73 @@ static void config_add_optstr(struct json_object *config, int optid)
config_add_str(config, optid, get_arg(optid));
}
+static void config_mix2_cb(void *closure, struct json_object *obj, const char *name)
+{
+ struct json_object *dest, *base = closure;
+
+ if (!name)
+ name = "";
+
+ if (!json_object_object_get_ex(base, name, &dest)) {
+ dest = joomchk(json_object_new_object());
+ json_object_object_add(base, name, dest);
+ }
+ if (json_object_is_type(obj, json_type_object))
+ wrap_json_object_add(dest, obj);
+ else
+ json_object_object_add(dest, "", json_object_get(obj));
+}
+
+static void config_mix2(struct json_object *config, int optid, struct json_object *val)
+{
+ struct json_object *obj;
+
+ if (!json_object_object_get_ex(config, name_of_optid(optid), &obj)) {
+ obj = joomchk(json_object_new_object());
+ json_object_object_add(config, name_of_optid(optid), obj);
+ }
+ wrap_json_for_all(val, config_mix2_cb, obj);
+}
+
+static void config_mix2_str(struct json_object *config, int optid, const char *val)
+{
+ size_t st1, st2;
+ const char *api, *key;
+ struct json_object *obj, *sub;
+ enum json_tokener_error jerr;
+
+ st1 = strcspn(val, "/:{[\"");
+ st2 = strcspn(&val[st1], ":{[\"");
+ if (val[st1] != '/' || val[st1 + st2] != ':') {
+ obj = json_tokener_parse_verbose(val, &jerr);
+ if (jerr != json_tokener_success)
+ obj = json_object_new_string(val);
+ } else {
+ api = st1 == 0 ? "*" : strndupa(val, st1);
+ val += st1 + 1;
+ key = st2 <= 1 || (st2 == 2 && *val == '*') ? NULL : strndupa(val, st2 - 1);
+ val += st2;
+ sub = json_tokener_parse_verbose(val, &jerr);
+ if (jerr != json_tokener_success)
+ sub = json_object_new_string(val);
+
+ if (key) {
+ obj = json_object_new_object();
+ json_object_object_add(obj, key, sub);
+ sub = obj;
+ }
+ obj = json_object_new_object();
+ json_object_object_add(obj, api, sub);
+ }
+ config_mix2(config, optid, obj);
+ json_object_put(obj);
+}
+
+static void config_mix2_optstr(struct json_object *config, int optid)
+{
+ config_mix2_str(config, optid, get_arg(optid));
+}
+
/*---------------------------------------------------------
| set the log levels
+--------------------------------------------------------- */
@@ -610,7 +705,7 @@ static void set_log(const char *args)
static void parse_arguments_inner(int argc, char **argv, struct json_object *config, struct option *options)
{
struct json_object *conf;
- int optid, cind;
+ int optid, cind, dodump = 0;
for (;;) {
cind = optind;
@@ -672,6 +767,10 @@ static void parse_arguments_inner(int argc, char **argv, struct json_object *con
config_add_optstr(config, optid);
break;
+ case ADD_SET:
+ config_mix2_optstr(config, optid);
+ break;
+
#if defined(WITH_MONITORING_OPTION)
case SET_MONITORING:
#endif
@@ -739,6 +838,11 @@ static void parse_arguments_inner(int argc, char **argv, struct json_object *con
json_object_put(conf);
break;
+ case DUMP_CONFIG:
+ noarg(optid);
+ dodump = 1;
+ break;
+
case GET_VERSION:
noarg(optid);
printVersion(stdout);
@@ -754,6 +858,11 @@ static void parse_arguments_inner(int argc, char **argv, struct json_object *con
}
}
/* TODO: check for extra value */
+
+ if (dodump) {
+ dump(config, stdout, NULL, NULL);
+ exit(0);
+ }
}
static void parse_arguments(int argc, char **argv, struct json_object *config)
@@ -807,45 +916,17 @@ static void fulfill_config(struct json_object *config)
#endif
}
-static void dump(struct json_object *config, FILE *file, const char *prefix, const char *title)
-{
- char z;
- const char *head, *tail;
-
- if (!prefix) {
- z = 0;
- prefix = &z;
- }
-
- if (title)
- fprintf(file, "%s----BEGIN OF %s-----\n", prefix, title);
-
- head = json_object_to_json_string_ext(config, JSON_C_TO_STRING_PRETTY
- |JSON_C_TO_STRING_SPACED|JSON_C_TO_STRING_NOSLASHESCAPE);
-
- if (head) {
- while(*head) {
- for (tail = head ; *tail && *tail != '\n' ; tail++);
- fprintf(file, "%s %.*s\n", prefix, (int)(tail - head), head);
- head = tail + !!*tail;
- }
- }
-
- if (title)
- fprintf(file, "%s----END OF %s-----\n", prefix, title);
-}
-
void afb_config_dump(struct json_object *config)
{
dump(config, stderr, "--", "CONFIG");
}
-static void on_environment_add(struct json_object *config, int optid, const char *name)
+static void on_environment(struct json_object *config, int optid, const char *name, void (*func)(struct json_object*, int, const char*))
{
char *value = getenv(name);
if (value && *value)
- config_add_str(config, optid, value);
+ func(config, optid, value);
}
static void on_environment_enum(struct json_object *config, int optid, const char *name, int (*func)(const char*))
@@ -867,7 +948,8 @@ static void parse_environment(struct json_object *config)
on_environment_enum(config, SET_TRACESES, "AFB_TRACESES", afb_hook_flags_session_from_text);
on_environment_enum(config, SET_TRACEAPI, "AFB_TRACEAPI", afb_hook_flags_api_from_text);
on_environment_enum(config, SET_TRACEGLOB, "AFB_TRACEGLOB", afb_hook_flags_global_from_text);
- on_environment_add(config, ADD_LDPATH, "AFB_LDPATHS");
+ on_environment(config, ADD_LDPATH, "AFB_LDPATHS", config_add_str);
+ on_environment(config, ADD_SET, "AFB_SET", config_mix2_str);
#if !defined(REMOVE_LEGACY_TRACE)
on_environment_enum(config, SET_TRACEDITF, "AFB_TRACEDITF", afb_hook_flags_legacy_ditf_from_text);
on_environment_enum(config, SET_TRACESVC, "AFB_TRACESVC", afb_hook_flags_legacy_svc_from_text);
diff --git a/src/afb-export.c b/src/afb-export.c
index e9d5d9ad..c1a716fc 100644
--- a/src/afb-export.c
+++ b/src/afb-export.c
@@ -51,6 +51,7 @@
#include "jobs.h"
#include "verbose.h"
#include "sig-monitor.h"
+#include "wrap-json.h"
/*************************************************************************
* internal types
@@ -139,6 +140,9 @@ struct afb_export
/* event handler list */
struct event_handler *event_handlers;
+ /* settings */
+ struct json_object *settings;
+
/* internal descriptors */
union {
#if defined(WITH_LEGACY_BINDING_V1)
@@ -199,6 +203,41 @@ struct afb_api_x3 *afb_export_to_api_x3(struct afb_export *export)
******************************************************************************
******************************************************************************
******************************************************************************
+ SETTINGS
+ ******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
+ ******************************************************************************/
+
+static struct json_object *configuration;
+
+void afb_export_set_config(struct json_object *config)
+{
+ struct json_object *save = configuration;
+ configuration = json_object_get(config);
+ json_object_put(save);
+}
+
+static struct json_object *get_settings(const char *name)
+{
+ struct json_object *result;
+ struct json_object *obj;
+
+ if (json_object_object_get_ex(configuration, "*", &obj))
+ result = wrap_json_clone(obj);
+ else
+ result = json_object_new_object();
+
+ if (json_object_object_get_ex(configuration, name, &obj))
+ wrap_json_object_add(result, obj);
+
+ return result;
+}
+
+/******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
F R O M D I T F
******************************************************************************
******************************************************************************
@@ -867,6 +906,17 @@ static int delete_api_cb(struct afb_api_x3 *api)
return 0;
}
+static struct json_object *settings_cb(struct afb_api_x3 *api)
+{
+ struct afb_export *export = from_api_x3(api);
+ struct json_object *result = export->settings;
+ if (!result) {
+ result = get_settings(export->name);
+ export->settings = result;
+ }
+ return result;
+}
+
static int hooked_api_set_verbs_v2_cb(
struct afb_api_x3 *api,
const struct afb_verb_v2 *verbs)
@@ -980,6 +1030,14 @@ static int hooked_delete_api_cb(struct afb_api_x3 *api)
return result;
}
+static struct json_object *hooked_settings_cb(struct afb_api_x3 *api)
+{
+ struct afb_export *export = from_api_x3(api);
+ struct json_object *result = settings_cb(api);
+ result = afb_hook_api_settings(export, result);
+ return result;
+}
+
static const struct afb_api_x3_itf api_x3_itf = {
.vverbose = (void*)vverbose_cb,
@@ -1018,6 +1076,7 @@ static const struct afb_api_x3_itf api_x3_itf = {
.class_require = class_require_cb,
.delete_api = delete_api_cb,
+ .settings = settings_cb,
};
static const struct afb_api_x3_itf hooked_api_x3_itf = {
@@ -1058,6 +1117,7 @@ static const struct afb_api_x3_itf hooked_api_x3_itf = {
.class_require = hooked_class_require_cb,
.delete_api = hooked_delete_api_cb,
+ .settings = hooked_settings_cb,
};
/******************************************************************************
@@ -1267,6 +1327,7 @@ void afb_export_destroy(struct afb_export *export)
afb_apiset_unref(export->call_set);
if (export->api.apiname != export->name)
free((void*)export->api.apiname);
+ json_object_put(export->settings);
free(export);
}
}
diff --git a/src/afb-export.h b/src/afb-export.h
index be8adfd5..0bee1747 100644
--- a/src/afb-export.h
+++ b/src/afb-export.h
@@ -30,6 +30,8 @@ struct afb_api_v3;
struct afb_api_x3;
struct afb_event_x2;
+extern void afb_export_set_config(struct json_object *config);
+
extern struct afb_export *afb_export_create_none_for_path(
struct afb_apiset *declare_set,
struct afb_apiset *call_set,
diff --git a/src/afb-hook-flags.c b/src/afb-hook-flags.c
index 738e54ce..57987356 100644
--- a/src/afb-hook-flags.c
+++ b/src/afb-hook-flags.c
@@ -112,6 +112,7 @@ static struct flag api_flags[] = { /* must be sorted by names */
{ "require_api", afb_hook_flag_api_require_api },
{ "rootdir_get_fd", afb_hook_flag_api_rootdir_get_fd },
{ "rootdir_open_locale",afb_hook_flag_api_rootdir_open_locale },
+ { "settings", afb_hook_flag_api_settings },
{ "start", afb_hook_flag_api_start },
{ "vverbose", afb_hook_flag_api_vverbose },
};
diff --git a/src/afb-hook.c b/src/afb-hook.c
index 6b655301..592f92a4 100644
--- a/src/afb-hook.c
+++ b/src/afb-hook.c
@@ -913,6 +913,11 @@ static void hook_api_on_event_handler_after_cb(void *closure, const struct afb_h
_hook_api_(export, "on_event_handler[%s].after(%s, %d, %s)", pattern, event, event_x2, json_object_to_json_string_ext(object, JSON_C_TO_STRING_NOSLASHESCAPE));
}
+static void hook_api_settings_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, struct json_object *object)
+{
+ _hook_api_(export, "settings -> %s", json_object_to_json_string_ext(object, JSON_C_TO_STRING_NOSLASHESCAPE));
+}
+
static struct afb_hook_api_itf hook_api_default_itf = {
.hook_api_event_broadcast_before = hook_api_event_broadcast_before_cb,
.hook_api_event_broadcast_after = hook_api_event_broadcast_after_cb,
@@ -952,6 +957,7 @@ static struct afb_hook_api_itf hook_api_default_itf = {
.hook_api_delete_api = hook_api_delete_api_cb,
.hook_api_on_event_handler_before = hook_api_on_event_handler_before_cb,
.hook_api_on_event_handler_after = hook_api_on_event_handler_after_cb,
+ .hook_api_settings = hook_api_settings_cb,
};
/******************************************************************************
@@ -1189,6 +1195,12 @@ void afb_hook_api_on_event_handler_after(const struct afb_export *export, const
_HOOK_API_2_(on_event_handler, on_event_handler_after, export, event, event_x2, object, pattern);
}
+struct json_object *afb_hook_api_settings(const struct afb_export *export, struct json_object *object)
+{
+ _HOOK_API_(settings, export, object);
+ return object;
+}
+
/******************************************************************************
* section: hooking export
*****************************************************************************/
diff --git a/src/afb-hook.h b/src/afb-hook.h
index f315cc08..76022ede 100644
--- a/src/afb-hook.h
+++ b/src/afb-hook.h
@@ -197,6 +197,7 @@ extern struct json_object *afb_hook_xreq_get_client_info(const struct afb_xreq *
#define afb_hook_flag_api_on_event 0x04000000
#define afb_hook_flag_api_legacy_unstore_req 0x08000000
#define afb_hook_flag_api_on_event_handler 0x10000000
+#define afb_hook_flag_api_settings 0x20000000
/* common flags */
/* extra flags */
@@ -208,7 +209,8 @@ extern struct json_object *afb_hook_xreq_get_client_info(const struct afb_xreq *
|afb_hook_flag_api_call\
|afb_hook_flag_api_callsync\
|afb_hook_flag_api_start\
- |afb_hook_flag_api_queue_job)
+ |afb_hook_flag_api_queue_job\
+ |afb_hook_flag_api_settings)
#define afb_hook_flags_api_extra (afb_hook_flag_api_get_event_loop\
@@ -311,6 +313,7 @@ struct afb_hook_api_itf {
void (*hook_api_delete_api)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, int result);
void (*hook_api_on_event_handler_before)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *event, int event_x2, struct json_object *object, const char *pattern);
void (*hook_api_on_event_handler_after)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *event, int event_x2, struct json_object *object, const char *pattern);
+ void (*hook_api_settings)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, struct json_object *object);
};
extern void afb_hook_api_event_broadcast_before(const struct afb_export *export, const char *name, struct json_object *object);
@@ -351,6 +354,7 @@ extern int afb_hook_api_class_require(const struct afb_export *export, int resul
extern int afb_hook_api_delete_api(const struct afb_export *export, int result);
extern void afb_hook_api_on_event_handler_before(const struct afb_export *export, const char *event, int event_x2, struct json_object *object, const char *pattern);
extern void afb_hook_api_on_event_handler_after(const struct afb_export *export, const char *event, int event_x2, struct json_object *object, const char *pattern);
+extern struct json_object *afb_hook_api_settings(const struct afb_export *export, struct json_object *object);
extern int afb_hook_flags_api(const char *api);
extern struct afb_hook_api *afb_hook_create_api(const char *api, int flags, struct afb_hook_api_itf *itf, void *closure);
diff --git a/src/afb-trace.c b/src/afb-trace.c
index 3f773953..aaa16352 100644
--- a/src/afb-trace.c
+++ b/src/afb-trace.c
@@ -717,6 +717,23 @@ static void hook_api_delete_api(void *closure, const struct afb_hookid *hookid,
hook_api(closure, hookid, export, "delete_api", "{si}", "status", result);
}
+static void hook_api_on_event_handler_before(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *event, int event_x2, struct json_object *object, const char *pattern)
+{
+ hook_api(closure, hookid, export, "on_event_handler.before",
+ "{ss ss sO?}", "pattern", pattern, "event", event, "data", object);
+}
+
+static void hook_api_on_event_handler_after(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *event, int event_x2, struct json_object *object, const char *pattern)
+{
+ hook_api(closure, hookid, export, "on_event_handler.after",
+ "{ss ss sO?}", "pattern", pattern, "event", event, "data", object);
+}
+
+static void hook_api_settings(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, struct json_object *object)
+{
+ hook_api(closure, hookid, export, "settings", "{sO}", "settings", object);
+}
+
static struct afb_hook_api_itf hook_api_itf = {
.hook_api_event_broadcast_before = hook_api_event_broadcast_before,
.hook_api_event_broadcast_after = hook_api_event_broadcast_after,
@@ -754,6 +771,9 @@ static struct afb_hook_api_itf hook_api_itf = {
.hook_api_class_provide = hook_api_class_provide,
.hook_api_class_require = hook_api_class_require,
.hook_api_delete_api = hook_api_delete_api,
+ .hook_api_on_event_handler_before = hook_api_on_event_handler_before,
+ .hook_api_on_event_handler_after = hook_api_on_event_handler_after,
+ .hook_api_settings = hook_api_settings,
};
/*******************************************************************************/
diff --git a/src/main-afb-daemon.c b/src/main-afb-daemon.c
index df0efbcc..d5d2aae2 100644
--- a/src/main-afb-daemon.c
+++ b/src/main-afb-daemon.c
@@ -52,6 +52,7 @@
#include "afb-session.h"
#include "verbose.h"
#include "afb-common.h"
+#include "afb-export.h"
#include "afb-monitor.h"
#include "afb-hook.h"
#include "afb-hook-flags.h"
@@ -604,6 +605,7 @@ static void start(int signum, void *arg)
{
const char *tracereq, *traceapi, *traceevt, *traceses, *tracesvc, *traceditf, *traceglob;
const char *workdir, *rootdir, *token, *rootapi;
+ struct json_object *settings;
struct afb_hsrv *hsrv;
int max_session_count, session_timeout, api_timeout;
int no_httpd, http_port;
@@ -617,6 +619,7 @@ static void start(int signum, void *arg)
exit(1);
}
+ settings = NULL;
token = rootapi = tracesvc = traceditf = tracereq =
traceapi = traceevt = traceses = traceglob = NULL;
no_httpd = http_port = 0;
@@ -624,6 +627,7 @@ static void start(int signum, void *arg)
"ss ss s?s"
"si si si"
"s?b s?i s?s"
+ "s?o"
#if !defined(REMOVE_LEGACY_TRACE)
"s?s s?s"
#endif
@@ -642,6 +646,7 @@ static void start(int signum, void *arg)
"port", &http_port,
"rootapi", &rootapi,
+ "set", &settings,
#if !defined(REMOVE_LEGACY_TRACE)
"tracesvc", &tracesvc,
"traceditf", &traceditf,
@@ -669,6 +674,7 @@ static void start(int signum, void *arg)
}
/* configure the daemon */
+ afb_export_set_config(settings);
if (afb_session_init(max_session_count, session_timeout, token)) {
ERROR("initialisation of session manager failed");
goto error;