#include "jobs.h"
#include "verbose.h"
#include "sig-monitor.h"
+#include "wrap-json.h"
/*************************************************************************
* internal types
/* event handler list */
struct event_handler *event_handlers;
+ /* creator if any */
+ struct afb_export *creator;
+
+ /* path indication if any */
+ const char *path;
+
+ /* settings */
+ struct json_object *settings;
+
/* internal descriptors */
union {
#if defined(WITH_LEGACY_BINDING_V1)
return to_api_x3(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 *make_settings(struct afb_export *export)
+{
+ struct json_object *result;
+ struct json_object *obj;
+ struct afb_export *iter;
+ char *path;
+
+ /* clone the globals */
+ if (json_object_object_get_ex(configuration, "*", &obj))
+ result = wrap_json_clone(obj);
+ else
+ result = json_object_new_object();
+
+ /* add locals */
+ if (json_object_object_get_ex(configuration, export->name, &obj))
+ wrap_json_object_add(result, obj);
+
+ /* add library path */
+ for (iter = export ; iter && !iter->path ; iter = iter->creator);
+ if (iter) {
+ path = realpath(iter->path, NULL);
+ json_object_object_add(result, "binding-path", json_object_new_string(path));
+ free(path);
+ }
+
+ export->settings = result;
+ return result;
+}
+
/******************************************************************************
******************************************************************************
******************************************************************************
int rc, rc2;
char *iter, *end, save;
+ /* emit a warning about unexpected require in preinit */
+ if (export->state == Api_State_Pre_Init)
+ WARNING("[API %s] requiring apis in pre-init may lead to unexpected result (requires%s: %s)",
+ export->api.apiname, initialized ? " initialized" : "", name);
+
/* scan the names in a local copy */
rc = 0;
iter = strdupa(name);
void *preinit_closure)
{
struct afb_export *export = from_api_x3(closure);
- struct afb_api_v3 *apiv3 = afb_api_v3_create(export->declare_set, export->call_set, api, info, noconcurrency, preinit, preinit_closure, 1);
+ struct afb_api_v3 *apiv3 = afb_api_v3_create(
+ export->declare_set, export->call_set,
+ api, info, noconcurrency,
+ preinit, preinit_closure, 1,
+ export, NULL);
return apiv3 ? to_api_x3(afb_api_v3_export(apiv3)) : NULL;
}
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 = make_settings(export);
+ return result;
+}
+
static int hooked_api_set_verbs_v2_cb(
struct afb_api_x3 *api,
const struct afb_verb_v2 *verbs)
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,
.class_require = class_require_cb,
.delete_api = delete_api_cb,
+ .settings = settings_cb,
};
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,
};
/******************************************************************************
struct afb_apiset *declare_set,
struct afb_apiset *call_set,
const char *apiname,
+ const char *path,
enum afb_api_version version)
{
struct afb_export *export;
+ size_t lenapi;
/* session shared with other exports */
if (common_session == NULL) {
if (common_session == NULL)
return NULL;
}
- export = calloc(1, sizeof *export + strlen(apiname));
+ lenapi = strlen(apiname);
+ export = calloc(1, sizeof *export + lenapi + (path == apiname || !path ? 0 : strlen(path)));
if (!export)
errno = ENOMEM;
else {
export->refcount = 1;
strcpy(export->name, apiname);
export->api.apiname = export->name;
+ if (path == apiname)
+ export->path = export->name;
+ else if (path)
+ export->path = strcpy(&export->name[lenapi + 1], path);
export->version = version;
export->state = Api_State_Pre_Init;
export->session = afb_session_addref(common_session);
afb_session_unref(export->session);
afb_apiset_unref(export->declare_set);
afb_apiset_unref(export->call_set);
+ json_object_put(export->settings);
+ afb_export_unref(export->creator);
if (export->api.apiname != export->name)
free((void*)export->api.apiname);
free(export);
int (*creator)(void*, struct afb_api_x3*),
void *closure)
{
- struct afb_export *export = create(declare_set, call_set, path, Api_Version_None);
+ struct afb_export *export = create(declare_set, call_set, path, path, Api_Version_None);
if (export) {
afb_export_logmask_set(export, logmask);
afb_export_update_hooks(export);
}
#if defined(WITH_LEGACY_BINDING_V1)
-struct afb_export *afb_export_create_v1(
- struct afb_apiset *declare_set,
+struct afb_export *afb_export_create_v1(struct afb_apiset *declare_set,
struct afb_apiset *call_set,
const char *apiname,
int (*init)(struct afb_service_x1),
- void (*onevent)(const char*, struct json_object*))
+ void (*onevent)(const char*, struct json_object*),
+ const char* path)
{
- struct afb_export *export = create(declare_set, call_set, apiname, Api_Version_1);
+ struct afb_export *export = create(declare_set, call_set, apiname, path, Api_Version_1);
if (export) {
export->init.v1 = init;
export->on_any_event_v12 = onevent;
}
#endif
-struct afb_export *afb_export_create_v2(
- struct afb_apiset *declare_set,
+struct afb_export *afb_export_create_v2(struct afb_apiset *declare_set,
struct afb_apiset *call_set,
const char *apiname,
const struct afb_binding_v2 *binding,
struct afb_binding_data_v2 *data,
int (*init)(),
- void (*onevent)(const char*, struct json_object*))
+ void (*onevent)(const char*, struct json_object*),
+ const char* path)
{
- struct afb_export *export = create(declare_set, call_set, apiname, Api_Version_2);
+ struct afb_export *export = create(declare_set, call_set, apiname, path, Api_Version_2);
if (export) {
export->init.v2 = init;
export->on_any_event_v12 = onevent;
struct afb_export *afb_export_create_v3(struct afb_apiset *declare_set,
struct afb_apiset *call_set,
const char *apiname,
- struct afb_api_v3 *apiv3)
+ struct afb_api_v3 *apiv3,
+ struct afb_export* creator,
+ const char* path)
{
- struct afb_export *export = create(declare_set, call_set, apiname, Api_Version_3);
+ struct afb_export *export = create(declare_set, call_set, apiname, path, Api_Version_3);
if (export) {
export->unsealed = 1;
export->desc.v3 = apiv3;
+ export->creator = afb_export_addref(creator);
afb_export_logmask_set(export, logmask);
afb_export_update_hooks(export);
}
ERROR("can't declare export %s to set %s, ABORTING it!",
export->api.apiname,
afb_apiset_name(export->declare_set));
- afb_export_addref(export);
+ afb_export_unref(export);
}
}