diff options
author | José Bollo <jose.bollo@iot.bzh> | 2018-07-27 17:38:22 +0200 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2018-08-02 15:49:43 +0200 |
commit | 5ef271effacb83552f9ea56572c751c2f5a556b6 (patch) | |
tree | 3d5f6665bde93633b0eb6c648c9ab46951443526 /src | |
parent | e39610f8c9b2e6bbb8a460f7d7ccccbc5161b4ed (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.c | 150 | ||||
-rw-r--r-- | src/afb-export.c | 61 | ||||
-rw-r--r-- | src/afb-export.h | 2 | ||||
-rw-r--r-- | src/afb-hook-flags.c | 1 | ||||
-rw-r--r-- | src/afb-hook.c | 12 | ||||
-rw-r--r-- | src/afb-hook.h | 6 | ||||
-rw-r--r-- | src/afb-trace.c | 20 | ||||
-rw-r--r-- | src/main-afb-daemon.c | 6 |
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; |