-struct api_so_desc {
- struct AFB_plugin *plugin; /* descriptor */
- size_t apilength;
- void *handle; /* context of dlopen */
- struct AFB_interface interface; /* interface */
-};
-
-static int api_timeout = 15;
-
-static const char plugin_register_function[] = "pluginAfbV1Entry";
-
-static void afb_api_so_evmgr_push(struct api_so_desc *desc, const char *name, struct json_object *object)
-{
- size_t length;
- char *event;
-
- assert(desc->plugin != NULL);
- length = strlen(name);
- event = alloca(length + 2 + desc->apilength);
- memcpy(event, desc->plugin->v1.prefix, desc->apilength);
- event[desc->apilength] = '/';
- memcpy(event + desc->apilength + 1, name, length + 1);
- ctxClientEventSend(NULL, event, object);
-}
-
-static const struct afb_evmgr_itf evmgr_itf = {
- .push = (void*)afb_api_so_evmgr_push
-};
-
-static struct afb_evmgr afb_api_so_get_evmgr(struct api_so_desc *desc)
-{
- return (struct afb_evmgr){ .itf = &evmgr_itf, .closure = desc };
-}
-
-static const struct afb_daemon_itf daemon_itf = {
- .get_evmgr = (void*)afb_api_so_get_evmgr,
- .get_event_loop = (void*)afb_common_get_event_loop,
- .get_user_bus = (void*)afb_common_get_user_bus,
- .get_system_bus = (void*)afb_common_get_system_bus
-};
-
-struct monitoring {
- struct afb_req req;
- void (*action)(struct afb_req);
-};
-
-static void monitored_call(int signum, struct monitoring *data)
-{
- if (signum != 0)
- afb_req_fail_f(data->req, "aborted", "signal %s(%d) caught", strsignal(signum), signum);
- else
- data->action(data->req);
-}
-
-static void call_check(struct afb_req req, struct afb_context *context, const struct AFB_verb_desc_v1 *verb)
-{
- struct monitoring data;
-
- int stag = (int)(verb->session & AFB_SESSION_MASK);
-
- if (stag != AFB_SESSION_NONE) {
- if (!afb_context_check(context)) {
- afb_context_close(context);
- afb_req_fail(req, "failed", "invalid token's identity");
- return;
- }
- }
-
- if ((stag & AFB_SESSION_CREATE) != 0) {
- if (!afb_context_create(context)) {
- afb_context_close(context);
- afb_req_fail(req, "failed", "invalid creation state");
- return;
- }
- }
-
- if ((stag & (AFB_SESSION_CREATE | AFB_SESSION_RENEW)) != 0)
- afb_context_refresh(context);
-
- if ((stag & AFB_SESSION_CLOSE) != 0)
- afb_context_close(context);
-
- data.req = req;
- data.action = verb->callback;
- afb_sig_monitor((void*)monitored_call, &data, api_timeout);
-}
-
-static void call(struct api_so_desc *desc, struct afb_req req, struct afb_context *context, const char *verb, size_t lenverb)
-{
- const struct AFB_verb_desc_v1 *v;
-
- v = desc->plugin->v1.verbs;
- while (v->name && (strncasecmp(v->name, verb, lenverb) || v->name[lenverb]))
- v++;
- if (v->name)
- call_check(req, context, v);
- else
- afb_req_fail_f(req, "unknown-verb", "verb %.*s unknown within api %s", (int)lenverb, verb, desc->plugin->v1.prefix);
-}
-
-int afb_api_so_add_plugin(const char *path)