hooks: Allow to remove hooking (and/or trace)
[src/app-framework-binder.git] / src / afb-export.c
1 /*
2  * Copyright (C) 2016-2019 "IoT.bzh"
3  * Author: José Bollo <jose.bollo@iot.bzh>
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #define _GNU_SOURCE
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <errno.h>
23 #include <fnmatch.h>
24 #include <ctype.h>
25
26 #include <json-c/json.h>
27 #if !defined(JSON_C_TO_STRING_NOSLASHESCAPE)
28 #define JSON_C_TO_STRING_NOSLASHESCAPE 0
29 #endif
30
31 #define AFB_BINDING_VERSION 0
32 #include <afb/afb-binding.h>
33
34 #include "afb-api.h"
35 #include "afb-apiset.h"
36 #if defined(WITH_LEGACY_BINDING_V1)
37 #include "afb-api-so-v1.h"
38 #endif
39 #include "afb-api-so-v2.h"
40 #include "afb-api-v3.h"
41 #include "afb-common.h"
42 #include "afb-cred.h"
43 #include "afb-evt.h"
44 #include "afb-export.h"
45 #include "afb-hook.h"
46 #include "afb-msg-json.h"
47 #include "afb-session.h"
48 #include "afb-xreq.h"
49 #include "afb-calls.h"
50
51 #include "systemd.h"
52 #include "jobs.h"
53 #include "verbose.h"
54 #include "globset.h"
55 #include "sig-monitor.h"
56 #include "wrap-json.h"
57
58 /*************************************************************************
59  * internal types
60  ************************************************************************/
61
62 /*
63  * Actually supported versions
64  */
65 enum afb_api_version
66 {
67         Api_Version_None = 0,
68 #if defined(WITH_LEGACY_BINDING_V1)
69         Api_Version_1 = 1,
70 #endif
71         Api_Version_2 = 2,
72         Api_Version_3 = 3
73 };
74
75 /*
76  * The states of exported APIs
77  */
78 enum afb_api_state
79 {
80         Api_State_Pre_Init,
81         Api_State_Init,
82         Api_State_Run
83 };
84
85 /*
86  * structure of the exported API
87  */
88 struct afb_export
89 {
90         /* keep it first */
91         struct afb_api_x3 api;
92
93         /* reference count */
94         int refcount;
95
96         /* version of the api */
97         unsigned version: 4;
98
99         /* current state */
100         unsigned state: 4;
101
102         /* declared */
103         unsigned declared: 1;
104
105         /* unsealed */
106         unsigned unsealed: 1;
107
108 #if WITH_AFB_HOOK
109         /* hooking flags */
110         int hookditf;
111         int hooksvc;
112 #endif
113
114         /* session for service */
115         struct afb_session *session;
116
117         /* apiset the API is declared in */
118         struct afb_apiset *declare_set;
119
120         /* apiset for calls */
121         struct afb_apiset *call_set;
122
123         /* event listener for service or NULL */
124         struct afb_evt_listener *listener;
125
126         /* event handler list */
127         struct globset *event_handlers;
128
129         /* creator if any */
130         struct afb_export *creator;
131
132         /* path indication if any */
133         const char *path;
134
135         /* settings */
136         struct json_object *settings;
137
138         /* internal descriptors */
139         union {
140 #if defined(WITH_LEGACY_BINDING_V1)
141                 struct afb_binding_v1 *v1;
142 #endif
143                 const struct afb_binding_v2 *v2;
144                 struct afb_api_v3 *v3;
145         } desc;
146
147         /* start function */
148         union {
149 #if defined(WITH_LEGACY_BINDING_V1)
150                 int (*v1)(struct afb_service_x1);
151 #endif
152                 int (*v2)();
153                 int (*v3)(struct afb_api_x3 *api);
154         } init;
155
156         /* event handling */
157         void (*on_any_event_v12)(const char *event, struct json_object *object);
158         void (*on_any_event_v3)(struct afb_api_x3 *api, const char *event, struct json_object *object);
159
160         /* exported data */
161         union {
162 #if defined(WITH_LEGACY_BINDING_V1)
163                 struct afb_binding_interface_v1 v1;
164 #endif
165                 struct afb_binding_data_v2 *v2;
166         } export;
167
168         /* initial name */
169         char name[1];
170 };
171
172 /*****************************************************************************/
173
174 static inline struct afb_api_x3 *to_api_x3(struct afb_export *export)
175 {
176         return (struct afb_api_x3*)export;
177 }
178
179 static inline struct afb_export *from_api_x3(struct afb_api_x3 *api)
180 {
181         return (struct afb_export*)api;
182 }
183
184 struct afb_export *afb_export_from_api_x3(struct afb_api_x3 *api)
185 {
186         return from_api_x3(api);
187 }
188
189 struct afb_api_x3 *afb_export_to_api_x3(struct afb_export *export)
190 {
191         return to_api_x3(export);
192 }
193
194 /******************************************************************************
195  ******************************************************************************
196  ******************************************************************************
197  ******************************************************************************
198         SETTINGS
199  ******************************************************************************
200  ******************************************************************************
201  ******************************************************************************
202  ******************************************************************************/
203
204 static struct json_object *configuration;
205
206 void afb_export_set_config(struct json_object *config)
207 {
208         struct json_object *save = configuration;
209         configuration = json_object_get(config);
210         json_object_put(save);
211 }
212
213 static struct json_object *make_settings(struct afb_export *export)
214 {
215         struct json_object *result;
216         struct json_object *obj;
217         struct afb_export *iter;
218         char *path;
219
220         /* clone the globals */
221         if (json_object_object_get_ex(configuration, "*", &obj))
222                 result = wrap_json_clone(obj);
223         else
224                 result = json_object_new_object();
225
226         /* add locals */
227         if (json_object_object_get_ex(configuration, export->name, &obj))
228                 wrap_json_object_add(result, obj);
229
230         /* add library path */
231         for (iter = export ; iter && !iter->path ; iter = iter->creator);
232         if (iter) {
233                 path = realpath(iter->path, NULL);
234                 json_object_object_add(result, "binding-path", json_object_new_string(path));
235                 free(path);
236         }
237
238         export->settings = result;
239         return result;
240 }
241
242 /******************************************************************************
243  ******************************************************************************
244  ******************************************************************************
245  ******************************************************************************
246                                            F R O M     D I T F
247  ******************************************************************************
248  ******************************************************************************
249  ******************************************************************************
250  ******************************************************************************/
251
252 /**********************************************
253 * normal flow
254 **********************************************/
255 static void vverbose_cb(struct afb_api_x3 *closure, int level, const char *file, int line, const char *function, const char *fmt, va_list args)
256 {
257         char *p;
258         struct afb_export *export = from_api_x3(closure);
259
260         if (!fmt || vasprintf(&p, fmt, args) < 0)
261                 vverbose(level, file, line, function, fmt, args);
262         else {
263                 verbose(level, file, line, function, (verbose_is_colorized() == 0 ? "[API %s] %s" : COLOR_API "[API %s]" COLOR_DEFAULT " %s"), export->api.apiname, p);
264                 free(p);
265         }
266 }
267
268 static void legacy_vverbose_v1_cb(struct afb_api_x3 *closure, int level, const char *file, int line, const char *fmt, va_list args)
269 {
270         vverbose_cb(closure, level, file, line, NULL, fmt, args);
271 }
272
273 static struct afb_event_x2 *event_x2_make_cb(struct afb_api_x3 *closure, const char *name)
274 {
275         struct afb_export *export = from_api_x3(closure);
276
277         /* check daemon state */
278         if (export->state == Api_State_Pre_Init) {
279                 ERROR("[API %s] Bad call to 'afb_daemon_event_make(%s)', must not be in PreInit", export->api.apiname, name);
280                 errno = EINVAL;
281                 return NULL;
282         }
283
284         /* create the event */
285         return afb_evt_event_x2_create2(export->api.apiname, name);
286 }
287
288 static struct afb_event_x1 legacy_event_x1_make_cb(struct afb_api_x3 *closure, const char *name)
289 {
290         struct afb_event_x2 *event = event_x2_make_cb(closure, name);
291         return afb_evt_event_from_evtid(afb_evt_event_x2_to_evtid(event));
292 }
293
294 static int event_broadcast_cb(struct afb_api_x3 *closure, const char *name, struct json_object *object)
295 {
296         size_t plen, nlen;
297         char *event;
298         struct afb_export *export = from_api_x3(closure);
299
300         /* check daemon state */
301         if (export->state == Api_State_Pre_Init) {
302                 ERROR("[API %s] Bad call to 'afb_daemon_event_broadcast(%s, %s)', must not be in PreInit",
303                         export->api.apiname, name, json_object_to_json_string_ext(object, JSON_C_TO_STRING_NOSLASHESCAPE));
304                 errno = EINVAL;
305                 return 0;
306         }
307
308         /* makes the event name */
309         plen = strlen(export->api.apiname);
310         nlen = strlen(name);
311         event = alloca(nlen + plen + 2);
312         memcpy(event, export->api.apiname, plen);
313         event[plen] = '/';
314         memcpy(event + plen + 1, name, nlen + 1);
315
316         /* broadcast the event */
317         return afb_evt_broadcast(event, object);
318 }
319
320 static struct sd_event *get_event_loop(struct afb_api_x3 *closure)
321 {
322         jobs_acquire_event_manager();
323         return systemd_get_event_loop();
324 }
325
326 static struct sd_bus *get_user_bus(struct afb_api_x3 *closure)
327 {
328         jobs_acquire_event_manager();
329         return systemd_get_user_bus();
330 }
331
332 static struct sd_bus *get_system_bus(struct afb_api_x3 *closure)
333 {
334         jobs_acquire_event_manager();
335         return systemd_get_system_bus();
336 }
337
338 static int rootdir_open_locale_cb(struct afb_api_x3 *closure, const char *filename, int flags, const char *locale)
339 {
340         return afb_common_rootdir_open_locale(filename, flags, locale);
341 }
342
343 static int queue_job_cb(struct afb_api_x3 *closure, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout)
344 {
345         return jobs_queue(group, timeout, callback, argument);
346 }
347
348 static struct afb_req_x1 legacy_unstore_req_cb(struct afb_api_x3 *closure, struct afb_stored_req *sreq)
349 {
350         return afb_xreq_unstore(sreq);
351 }
352
353 static int require_api_cb(struct afb_api_x3 *closure, const char *name, int initialized)
354 {
355         struct afb_export *export = from_api_x3(closure);
356         int rc, rc2;
357         char *iter, *end, save;
358
359         /* emit a warning about unexpected require in preinit */
360         if (export->state == Api_State_Pre_Init)
361                 WARNING("[API %s] requiring apis in pre-init may lead to unexpected result (requires%s: %s)",
362                         export->api.apiname, initialized ? " initialized" : "", name);
363
364         /* scan the names in a local copy */
365         rc = 0;
366         iter = strdupa(name);
367         for(;;) {
368                 /* skip any space */
369                 save = *iter;
370                 while(isspace(save))
371                         save = *++iter;
372                 if (!save) /* at end? */
373                         return rc;
374
375                 /* search for the end */
376                 end = iter;
377                 while (save && !isspace(save))
378                         save = *++end;
379                 *end = 0;
380
381                 /* check the required api */
382                 if (export->state == Api_State_Pre_Init)
383                         rc2 = afb_apiset_require(export->declare_set, export->api.apiname, name);
384                 else
385                         rc2 = -!((initialized ? afb_apiset_lookup_started : afb_apiset_lookup)(export->call_set, iter, 1));
386                 if (rc2 < 0)
387                         rc = rc2;
388
389                 *end = save;
390                 iter = end;
391         }
392 }
393
394 static int add_alias_cb(struct afb_api_x3 *closure, const char *apiname, const char *aliasname)
395 {
396         struct afb_export *export = from_api_x3(closure);
397         if (!afb_api_is_valid_name(aliasname)) {
398                 ERROR("[API %s] Can't add alias to %s: bad API name", export->api.apiname, aliasname);
399                 errno = EINVAL;
400                 return -1;
401         }
402         NOTICE("[API %s] aliasing [API %s] to [API %s]", export->api.apiname, apiname?:"<null>", aliasname);
403         afb_export_add_alias(export, apiname, aliasname);
404         return 0;
405 }
406
407 static struct afb_api_x3 *api_new_api_cb(
408                 struct afb_api_x3 *closure,
409                 const char *api,
410                 const char *info,
411                 int noconcurrency,
412                 int (*preinit)(void*, struct afb_api_x3 *),
413                 void *preinit_closure)
414 {
415         struct afb_export *export = from_api_x3(closure);
416         struct afb_api_v3 *apiv3 = afb_api_v3_create(
417                                         export->declare_set, export->call_set,
418                                         api, info, noconcurrency,
419                                         preinit, preinit_closure, 1,
420                                         export, NULL);
421         return apiv3 ? to_api_x3(afb_api_v3_export(apiv3)) : NULL;
422 }
423
424 static const struct afb_daemon_itf_x1 daemon_itf = {
425         .vverbose_v1 = legacy_vverbose_v1_cb,
426         .vverbose_v2 = vverbose_cb,
427         .event_make = legacy_event_x1_make_cb,
428         .event_broadcast = event_broadcast_cb,
429         .get_event_loop = get_event_loop,
430         .get_user_bus = get_user_bus,
431         .get_system_bus = get_system_bus,
432         .rootdir_get_fd = afb_common_rootdir_get_fd,
433         .rootdir_open_locale = rootdir_open_locale_cb,
434         .queue_job = queue_job_cb,
435         .unstore_req = legacy_unstore_req_cb,
436         .require_api = require_api_cb,
437         .add_alias = add_alias_cb,
438         .new_api = api_new_api_cb,
439 };
440
441 #if WITH_AFB_HOOK
442 static void hooked_vverbose_cb(struct afb_api_x3 *closure, int level, const char *file, int line, const char *function, const char *fmt, va_list args)
443 {
444         struct afb_export *export = from_api_x3(closure);
445         va_list ap;
446         va_copy(ap, args);
447         vverbose_cb(closure, level, file, line, function, fmt, args);
448         afb_hook_api_vverbose(export, level, file, line, function, fmt, ap);
449         va_end(ap);
450 }
451
452 static void legacy_hooked_vverbose_v1_cb(struct afb_api_x3 *closure, int level, const char *file, int line, const char *fmt, va_list args)
453 {
454         hooked_vverbose_cb(closure, level, file, line, NULL, fmt, args);
455 }
456
457 static struct afb_event_x2 *hooked_event_x2_make_cb(struct afb_api_x3 *closure, const char *name)
458 {
459         struct afb_export *export = from_api_x3(closure);
460         struct afb_event_x2 *r = event_x2_make_cb(closure, name);
461         afb_hook_api_event_make(export, name, r);
462         return r;
463 }
464
465 static struct afb_event_x1 legacy_hooked_event_x1_make_cb(struct afb_api_x3 *closure, const char *name)
466 {
467         struct afb_event_x2 *event = hooked_event_x2_make_cb(closure, name);
468         struct afb_event_x1 e;
469         e.closure = event;
470         e.itf = event ? event->itf : NULL;
471         return e;
472 }
473
474 static int hooked_event_broadcast_cb(struct afb_api_x3 *closure, const char *name, struct json_object *object)
475 {
476         int r;
477         struct afb_export *export = from_api_x3(closure);
478         json_object_get(object);
479         afb_hook_api_event_broadcast_before(export, name, json_object_get(object));
480         r = event_broadcast_cb(closure, name, object);
481         afb_hook_api_event_broadcast_after(export, name, object, r);
482         json_object_put(object);
483         return r;
484 }
485
486 static struct sd_event *hooked_get_event_loop(struct afb_api_x3 *closure)
487 {
488         struct afb_export *export = from_api_x3(closure);
489         struct sd_event *r;
490
491         jobs_acquire_event_manager();
492         r = get_event_loop(closure);
493         return afb_hook_api_get_event_loop(export, r);
494 }
495
496 static struct sd_bus *hooked_get_user_bus(struct afb_api_x3 *closure)
497 {
498         struct afb_export *export = from_api_x3(closure);
499         struct sd_bus *r;
500
501         jobs_acquire_event_manager();
502         r = get_user_bus(closure);
503         return afb_hook_api_get_user_bus(export, r);
504 }
505
506 static struct sd_bus *hooked_get_system_bus(struct afb_api_x3 *closure)
507 {
508         struct afb_export *export = from_api_x3(closure);
509         struct sd_bus *r;
510
511         jobs_acquire_event_manager();
512         r = get_system_bus(closure);
513         return afb_hook_api_get_system_bus(export, r);
514 }
515
516 static int hooked_rootdir_get_fd(struct afb_api_x3 *closure)
517 {
518         struct afb_export *export = from_api_x3(closure);
519         int r = afb_common_rootdir_get_fd();
520         return afb_hook_api_rootdir_get_fd(export, r);
521 }
522
523 static int hooked_rootdir_open_locale_cb(struct afb_api_x3 *closure, const char *filename, int flags, const char *locale)
524 {
525         struct afb_export *export = from_api_x3(closure);
526         int r = rootdir_open_locale_cb(closure, filename, flags, locale);
527         return afb_hook_api_rootdir_open_locale(export, filename, flags, locale, r);
528 }
529
530 static int hooked_queue_job_cb(struct afb_api_x3 *closure, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout)
531 {
532         struct afb_export *export = from_api_x3(closure);
533         int r = queue_job_cb(closure, callback, argument, group, timeout);
534         return afb_hook_api_queue_job(export, callback, argument, group, timeout, r);
535 }
536
537 static struct afb_req_x1 legacy_hooked_unstore_req_cb(struct afb_api_x3 *closure, struct afb_stored_req *sreq)
538 {
539         struct afb_export *export = from_api_x3(closure);
540         afb_hook_api_legacy_unstore_req(export, sreq);
541         return legacy_unstore_req_cb(closure, sreq);
542 }
543
544 static int hooked_require_api_cb(struct afb_api_x3 *closure, const char *name, int initialized)
545 {
546         int result;
547         struct afb_export *export = from_api_x3(closure);
548         afb_hook_api_require_api(export, name, initialized);
549         result = require_api_cb(closure, name, initialized);
550         return afb_hook_api_require_api_result(export, name, initialized, result);
551 }
552
553 static int hooked_add_alias_cb(struct afb_api_x3 *closure, const char *apiname, const char *aliasname)
554 {
555         struct afb_export *export = from_api_x3(closure);
556         int result = add_alias_cb(closure, apiname, aliasname);
557         return afb_hook_api_add_alias(export, apiname, aliasname, result);
558 }
559
560 static struct afb_api_x3 *hooked_api_new_api_cb(
561                 struct afb_api_x3 *closure,
562                 const char *api,
563                 const char *info,
564                 int noconcurrency,
565                 int (*preinit)(void*, struct afb_api_x3 *),
566                 void *preinit_closure)
567 {
568         struct afb_api_x3 *result;
569         struct afb_export *export = from_api_x3(closure);
570         afb_hook_api_new_api_before(export, api, info, noconcurrency);
571         result = api_new_api_cb(closure, api, info, noconcurrency, preinit, preinit_closure);
572         afb_hook_api_new_api_after(export, -!result, api);
573         return result;
574 }
575
576 static const struct afb_daemon_itf_x1 hooked_daemon_itf = {
577         .vverbose_v1 = legacy_hooked_vverbose_v1_cb,
578         .vverbose_v2 = hooked_vverbose_cb,
579         .event_make = legacy_hooked_event_x1_make_cb,
580         .event_broadcast = hooked_event_broadcast_cb,
581         .get_event_loop = hooked_get_event_loop,
582         .get_user_bus = hooked_get_user_bus,
583         .get_system_bus = hooked_get_system_bus,
584         .rootdir_get_fd = hooked_rootdir_get_fd,
585         .rootdir_open_locale = hooked_rootdir_open_locale_cb,
586         .queue_job = hooked_queue_job_cb,
587         .unstore_req = legacy_hooked_unstore_req_cb,
588         .require_api = hooked_require_api_cb,
589         .add_alias = hooked_add_alias_cb,
590         .new_api = hooked_api_new_api_cb,
591 };
592 #endif
593
594 /******************************************************************************
595  ******************************************************************************
596  ******************************************************************************
597  ******************************************************************************
598                                            F R O M     S V C
599  ******************************************************************************
600  ******************************************************************************
601  ******************************************************************************
602  ******************************************************************************/
603
604 /* the common session for services sharing their session */
605 static struct afb_session *common_session;
606
607 /******************************************************************************
608  ******************************************************************************
609  ******************************************************************************
610  ******************************************************************************
611                                            F R O M     S V C
612  ******************************************************************************
613  ******************************************************************************
614  ******************************************************************************
615  ******************************************************************************/
616
617 static void call_x3(
618                 struct afb_api_x3 *apix3,
619                 const char *api,
620                 const char *verb,
621                 struct json_object *args,
622                 void (*callback)(void*, struct json_object*, const char *error, const char *info, struct afb_api_x3*),
623                 void *closure)
624 {
625         struct afb_export *export = from_api_x3(apix3);
626         return afb_calls_call(export, api, verb, args, callback, closure);
627 }
628
629 static int call_sync_x3(
630                 struct afb_api_x3 *apix3,
631                 const char *api,
632                 const char *verb,
633                 struct json_object *args,
634                 struct json_object **object,
635                 char **error,
636                 char **info)
637 {
638         struct afb_export *export = from_api_x3(apix3);
639         return afb_calls_call_sync(export, api, verb, args, object, error, info);
640 }
641
642 static void legacy_call_v12(
643                 struct afb_api_x3 *apix3,
644                 const char *api,
645                 const char *verb,
646                 struct json_object *args,
647                 void (*callback)(void*, int, struct json_object*),
648                 void *closure)
649 {
650         struct afb_export *export = from_api_x3(apix3);
651         afb_calls_legacy_call_v12(export, api, verb, args, callback, closure);
652 }
653
654 static void legacy_call_x3(
655                 struct afb_api_x3 *apix3,
656                 const char *api,
657                 const char *verb,
658                 struct json_object *args,
659                 void (*callback)(void*, int, struct json_object*, struct afb_api_x3*),
660                 void *closure)
661 {
662         struct afb_export *export = from_api_x3(apix3);
663         afb_calls_legacy_call_v3(export, api, verb, args, callback, closure);
664 }
665
666 static int legacy_call_sync(
667                 struct afb_api_x3 *apix3,
668                 const char *api,
669                 const char *verb,
670                 struct json_object *args,
671                 struct json_object **result)
672 {
673         struct afb_export *export = from_api_x3(apix3);
674         return afb_calls_legacy_call_sync(export, api, verb, args, result);
675 }
676
677 /* the interface for services */
678 static const struct afb_service_itf_x1 service_itf = {
679         .call = legacy_call_v12,
680         .call_sync = legacy_call_sync
681 };
682
683 #if WITH_AFB_HOOK
684 static void hooked_call_x3(
685                 struct afb_api_x3 *apix3,
686                 const char *api,
687                 const char *verb,
688                 struct json_object *args,
689                 void (*callback)(void*, struct json_object*, const char*, const char*, struct afb_api_x3*),
690                 void *closure)
691 {
692         struct afb_export *export = from_api_x3(apix3);
693         afb_calls_hooked_call(export, api, verb, args, callback, closure);
694 }
695
696 static int hooked_call_sync_x3(
697                 struct afb_api_x3 *apix3,
698                 const char *api,
699                 const char *verb,
700                 struct json_object *args,
701                 struct json_object **object,
702                 char **error,
703                 char **info)
704 {
705         struct afb_export *export = from_api_x3(apix3);
706         return afb_calls_hooked_call_sync(export, api, verb, args, object, error, info);
707 }
708
709 static void legacy_hooked_call_v12(
710                 struct afb_api_x3 *apix3,
711                 const char *api,
712                 const char *verb,
713                 struct json_object *args,
714                 void (*callback)(void*, int, struct json_object*),
715                 void *closure)
716 {
717         struct afb_export *export = from_api_x3(apix3);
718         afb_calls_legacy_hooked_call_v12(export, api, verb, args, callback, closure);
719 }
720
721 static void legacy_hooked_call_x3(
722                 struct afb_api_x3 *apix3,
723                 const char *api,
724                 const char *verb,
725                 struct json_object *args,
726                 void (*callback)(void*, int, struct json_object*, struct afb_api_x3*),
727                 void *closure)
728 {
729         struct afb_export *export = from_api_x3(apix3);
730         afb_calls_legacy_hooked_call_v3(export, api, verb, args, callback, closure);
731 }
732
733 static int legacy_hooked_call_sync(
734                 struct afb_api_x3 *apix3,
735                 const char *api,
736                 const char *verb,
737                 struct json_object *args,
738                 struct json_object **result)
739 {
740         struct afb_export *export = from_api_x3(apix3);
741         return afb_calls_legacy_hooked_call_sync(export, api, verb, args, result);
742 }
743
744 /* the interface for services */
745 static const struct afb_service_itf_x1 hooked_service_itf = {
746         .call = legacy_hooked_call_v12,
747         .call_sync = legacy_hooked_call_sync
748 };
749 #endif
750
751 /******************************************************************************
752  ******************************************************************************
753  ******************************************************************************
754  ******************************************************************************
755                                            F R O M     D Y N A P I
756  ******************************************************************************
757  ******************************************************************************
758  ******************************************************************************
759  ******************************************************************************/
760
761 static int api_set_verbs_v2_cb(
762                 struct afb_api_x3 *api,
763                 const struct afb_verb_v2 *verbs)
764 {
765         struct afb_export *export = from_api_x3(api);
766
767         if (export->unsealed) {
768                 afb_api_v3_set_verbs_v2(export->desc.v3, verbs);
769                 return 0;
770         }
771
772         errno = EPERM;
773         return -1;
774 }
775
776 static int api_set_verbs_v3_cb(
777                 struct afb_api_x3 *api,
778                 const struct afb_verb_v3 *verbs)
779 {
780         struct afb_export *export = from_api_x3(api);
781
782         if (!export->unsealed) {
783                 errno = EPERM;
784                 return -1;
785         }
786
787         afb_api_v3_set_verbs_v3(export->desc.v3, verbs);
788         return 0;
789 }
790
791 static int api_add_verb_cb(
792                 struct afb_api_x3 *api,
793                 const char *verb,
794                 const char *info,
795                 void (*callback)(struct afb_req_x2 *req),
796                 void *vcbdata,
797                 const struct afb_auth *auth,
798                 uint32_t session,
799                 int glob)
800 {
801         struct afb_export *export = from_api_x3(api);
802
803         if (!export->unsealed) {
804                 errno = EPERM;
805                 return -1;
806         }
807
808         return afb_api_v3_add_verb(export->desc.v3, verb, info, callback, vcbdata, auth, (uint16_t)session, glob);
809 }
810
811 static int api_del_verb_cb(
812                 struct afb_api_x3 *api,
813                 const char *verb,
814                 void **vcbdata)
815 {
816         struct afb_export *export = from_api_x3(api);
817
818         if (!export->unsealed) {
819                 errno = EPERM;
820                 return -1;
821         }
822
823         return afb_api_v3_del_verb(export->desc.v3, verb, vcbdata);
824 }
825
826 static int api_set_on_event_cb(
827                 struct afb_api_x3 *api,
828                 void (*onevent)(struct afb_api_x3 *api, const char *event, struct json_object *object))
829 {
830         struct afb_export *export = from_api_x3(api);
831         return afb_export_handle_events_v3(export, onevent);
832 }
833
834 static int api_set_on_init_cb(
835                 struct afb_api_x3 *api,
836                 int (*oninit)(struct afb_api_x3 *api))
837 {
838         struct afb_export *export = from_api_x3(api);
839
840         return afb_export_handle_init_v3(export, oninit);
841 }
842
843 static void api_seal_cb(
844                 struct afb_api_x3 *api)
845 {
846         struct afb_export *export = from_api_x3(api);
847
848         export->unsealed = 0;
849 }
850
851 static int event_handler_add_cb(
852                 struct afb_api_x3 *api,
853                 const char *pattern,
854                 void (*callback)(void *, const char*, struct json_object*, struct afb_api_x3*),
855                 void *closure)
856 {
857         struct afb_export *export = from_api_x3(api);
858
859         return afb_export_event_handler_add(export, pattern, callback, closure);
860 }
861
862 static int event_handler_del_cb(
863                 struct afb_api_x3 *api,
864                 const char *pattern,
865                 void **closure)
866 {
867         struct afb_export *export = from_api_x3(api);
868
869         return afb_export_event_handler_del(export, pattern, closure);
870 }
871
872 static int class_provide_cb(struct afb_api_x3 *api, const char *name)
873 {
874         struct afb_export *export = from_api_x3(api);
875
876         int rc = 0, rc2;
877         char *iter, *end, save;
878
879         iter = strdupa(name);
880         for(;;) {
881                 /* skip any space */
882                 save = *iter;
883                 while(isspace(save))
884                         save = *++iter;
885                 if (!save) /* at end? */
886                         return rc;
887
888                 /* search for the end */
889                 end = iter;
890                 while (save && !isspace(save))
891                         save = *++end;
892                 *end = 0;
893
894                 rc2 = afb_apiset_provide_class(export->declare_set, api->apiname, iter);
895                 if (rc2 < 0)
896                         rc = rc2;
897
898                 *end = save;
899                 iter = end;
900         }
901 }
902
903 static int class_require_cb(struct afb_api_x3 *api, const char *name)
904 {
905         struct afb_export *export = from_api_x3(api);
906
907         int rc = 0, rc2;
908         char *iter, *end, save;
909
910         iter = strdupa(name);
911         for(;;) {
912                 /* skip any space */
913                 save = *iter;
914                 while(isspace(save))
915                         save = *++iter;
916                 if (!save) /* at end? */
917                         return rc;
918
919                 /* search for the end */
920                 end = iter;
921                 while (save && !isspace(save))
922                         save = *++end;
923                 *end = 0;
924
925                 rc2 = afb_apiset_require_class(export->declare_set, api->apiname, iter);
926                 if (rc2 < 0)
927                         rc = rc2;
928
929                 *end = save;
930                 iter = end;
931         }
932 }
933
934 static int delete_api_cb(struct afb_api_x3 *api)
935 {
936         struct afb_export *export = from_api_x3(api);
937
938         if (!export->unsealed) {
939                 errno = EPERM;
940                 return -1;
941         }
942
943         afb_export_undeclare(export);
944         afb_export_unref(export);
945         return 0;
946 }
947
948 static struct json_object *settings_cb(struct afb_api_x3 *api)
949 {
950         struct afb_export *export = from_api_x3(api);
951         struct json_object *result = export->settings;
952         if (!result)
953                 result = make_settings(export);
954         return result;
955 }
956
957 static const struct afb_api_x3_itf api_x3_itf = {
958
959         .vverbose = (void*)vverbose_cb,
960
961         .get_event_loop = get_event_loop,
962         .get_user_bus = get_user_bus,
963         .get_system_bus = get_system_bus,
964         .rootdir_get_fd = afb_common_rootdir_get_fd,
965         .rootdir_open_locale = rootdir_open_locale_cb,
966         .queue_job = queue_job_cb,
967
968         .require_api = require_api_cb,
969         .add_alias = add_alias_cb,
970
971         .event_broadcast = event_broadcast_cb,
972         .event_make = event_x2_make_cb,
973
974         .legacy_call = legacy_call_x3,
975         .legacy_call_sync = legacy_call_sync,
976
977         .api_new_api = api_new_api_cb,
978         .api_set_verbs_v2 = api_set_verbs_v2_cb,
979         .api_add_verb = api_add_verb_cb,
980         .api_del_verb = api_del_verb_cb,
981         .api_set_on_event = api_set_on_event_cb,
982         .api_set_on_init = api_set_on_init_cb,
983         .api_seal = api_seal_cb,
984         .api_set_verbs_v3 = api_set_verbs_v3_cb,
985         .event_handler_add = event_handler_add_cb,
986         .event_handler_del = event_handler_del_cb,
987
988         .call = call_x3,
989         .call_sync = call_sync_x3,
990
991         .class_provide = class_provide_cb,
992         .class_require = class_require_cb,
993
994         .delete_api = delete_api_cb,
995         .settings = settings_cb,
996 };
997
998 #if WITH_AFB_HOOK
999 static int hooked_api_set_verbs_v2_cb(
1000                 struct afb_api_x3 *api,
1001                 const struct afb_verb_v2 *verbs)
1002 {
1003         struct afb_export *export = from_api_x3(api);
1004         int result = api_set_verbs_v2_cb(api, verbs);
1005         return afb_hook_api_api_set_verbs_v2(export, result, verbs);
1006 }
1007
1008 static int hooked_api_set_verbs_v3_cb(
1009                 struct afb_api_x3 *api,
1010                 const struct afb_verb_v3 *verbs)
1011 {
1012         struct afb_export *export = from_api_x3(api);
1013         int result = api_set_verbs_v3_cb(api, verbs);
1014         return afb_hook_api_api_set_verbs_v3(export, result, verbs);
1015 }
1016
1017 static int hooked_api_add_verb_cb(
1018                 struct afb_api_x3 *api,
1019                 const char *verb,
1020                 const char *info,
1021                 void (*callback)(struct afb_req_x2 *req),
1022                 void *vcbdata,
1023                 const struct afb_auth *auth,
1024                 uint32_t session,
1025                 int glob)
1026 {
1027         struct afb_export *export = from_api_x3(api);
1028         int result = api_add_verb_cb(api, verb, info, callback, vcbdata, auth, session, glob);
1029         return afb_hook_api_api_add_verb(export, result, verb, info, glob);
1030 }
1031
1032 static int hooked_api_del_verb_cb(
1033                 struct afb_api_x3 *api,
1034                 const char *verb,
1035                 void **vcbdata)
1036 {
1037         struct afb_export *export = from_api_x3(api);
1038         int result = api_del_verb_cb(api, verb, vcbdata);
1039         return afb_hook_api_api_del_verb(export, result, verb);
1040 }
1041
1042 static int hooked_api_set_on_event_cb(
1043                 struct afb_api_x3 *api,
1044                 void (*onevent)(struct afb_api_x3 *api, const char *event, struct json_object *object))
1045 {
1046         struct afb_export *export = from_api_x3(api);
1047         int result = api_set_on_event_cb(api, onevent);
1048         return afb_hook_api_api_set_on_event(export, result);
1049 }
1050
1051 static int hooked_api_set_on_init_cb(
1052                 struct afb_api_x3 *api,
1053                 int (*oninit)(struct afb_api_x3 *api))
1054 {
1055         struct afb_export *export = from_api_x3(api);
1056         int result = api_set_on_init_cb(api, oninit);
1057         return afb_hook_api_api_set_on_init(export, result);
1058 }
1059
1060 static void hooked_api_seal_cb(
1061                 struct afb_api_x3 *api)
1062 {
1063         struct afb_export *export = from_api_x3(api);
1064         afb_hook_api_api_seal(export);
1065         api_seal_cb(api);
1066 }
1067
1068 static int hooked_event_handler_add_cb(
1069                 struct afb_api_x3 *api,
1070                 const char *pattern,
1071                 void (*callback)(void *, const char*, struct json_object*, struct afb_api_x3*),
1072                 void *closure)
1073 {
1074         struct afb_export *export = from_api_x3(api);
1075         int result = event_handler_add_cb(api, pattern, callback, closure);
1076         return afb_hook_api_event_handler_add(export, result, pattern);
1077 }
1078
1079 static int hooked_event_handler_del_cb(
1080                 struct afb_api_x3 *api,
1081                 const char *pattern,
1082                 void **closure)
1083 {
1084         struct afb_export *export = from_api_x3(api);
1085         int result = event_handler_del_cb(api, pattern, closure);
1086         return afb_hook_api_event_handler_del(export, result, pattern);
1087 }
1088
1089 static int hooked_class_provide_cb(struct afb_api_x3 *api, const char *name)
1090 {
1091         struct afb_export *export = from_api_x3(api);
1092         int result = class_provide_cb(api, name);
1093         return afb_hook_api_class_provide(export, result, name);
1094 }
1095
1096 static int hooked_class_require_cb(struct afb_api_x3 *api, const char *name)
1097 {
1098         struct afb_export *export = from_api_x3(api);
1099         int result = class_require_cb(api, name);
1100         return afb_hook_api_class_require(export, result, name);
1101 }
1102
1103 static int hooked_delete_api_cb(struct afb_api_x3 *api)
1104 {
1105         struct afb_export *export = afb_export_addref(from_api_x3(api));
1106         int result = delete_api_cb(api);
1107         result = afb_hook_api_delete_api(export, result);
1108         afb_export_unref(export);
1109         return result;
1110 }
1111
1112 static struct json_object *hooked_settings_cb(struct afb_api_x3 *api)
1113 {
1114         struct afb_export *export = from_api_x3(api);
1115         struct json_object *result = settings_cb(api);
1116         result = afb_hook_api_settings(export, result);
1117         return result;
1118 }
1119
1120 static const struct afb_api_x3_itf hooked_api_x3_itf = {
1121
1122         .vverbose = hooked_vverbose_cb,
1123
1124         .get_event_loop = hooked_get_event_loop,
1125         .get_user_bus = hooked_get_user_bus,
1126         .get_system_bus = hooked_get_system_bus,
1127         .rootdir_get_fd = hooked_rootdir_get_fd,
1128         .rootdir_open_locale = hooked_rootdir_open_locale_cb,
1129         .queue_job = hooked_queue_job_cb,
1130
1131         .require_api = hooked_require_api_cb,
1132         .add_alias = hooked_add_alias_cb,
1133
1134         .event_broadcast = hooked_event_broadcast_cb,
1135         .event_make = hooked_event_x2_make_cb,
1136
1137         .legacy_call = legacy_hooked_call_x3,
1138         .legacy_call_sync = legacy_hooked_call_sync,
1139
1140         .api_new_api = hooked_api_new_api_cb,
1141         .api_set_verbs_v2 = hooked_api_set_verbs_v2_cb,
1142         .api_add_verb = hooked_api_add_verb_cb,
1143         .api_del_verb = hooked_api_del_verb_cb,
1144         .api_set_on_event = hooked_api_set_on_event_cb,
1145         .api_set_on_init = hooked_api_set_on_init_cb,
1146         .api_seal = hooked_api_seal_cb,
1147         .api_set_verbs_v3 = hooked_api_set_verbs_v3_cb,
1148         .event_handler_add = hooked_event_handler_add_cb,
1149         .event_handler_del = hooked_event_handler_del_cb,
1150
1151         .call = hooked_call_x3,
1152         .call_sync = hooked_call_sync_x3,
1153
1154         .class_provide = hooked_class_provide_cb,
1155         .class_require = hooked_class_require_cb,
1156
1157         .delete_api = hooked_delete_api_cb,
1158         .settings = hooked_settings_cb,
1159 };
1160 #endif
1161
1162 /******************************************************************************
1163  ******************************************************************************
1164  ******************************************************************************
1165  ******************************************************************************
1166                       L I S T E N E R S
1167  ******************************************************************************
1168  ******************************************************************************
1169  ******************************************************************************
1170  ******************************************************************************/
1171
1172 /*
1173  * Propagates the event to the service
1174  */
1175 static void listener_of_events(void *closure, const char *event, int eventid, struct json_object *object)
1176 {
1177         const struct globset_handler *handler;
1178         void (*callback)(void *, const char*, struct json_object*, struct afb_api_x3*);
1179         struct afb_export *export = from_api_x3(closure);
1180
1181 #if WITH_AFB_HOOK
1182         /* hook the event before */
1183         if (export->hooksvc & afb_hook_flag_api_on_event)
1184                 afb_hook_api_on_event_before(export, event, eventid, object);
1185 #endif
1186
1187         /* transmit to specific handlers */
1188         /* search the handler */
1189         handler = export->event_handlers ? globset_match(export->event_handlers, event) : NULL;
1190         if (handler) {
1191                 callback = handler->callback;
1192 #if WITH_AFB_HOOK
1193                 if (!(export->hooksvc & afb_hook_flag_api_on_event_handler))
1194 #endif
1195                         callback(handler->closure, event, object, to_api_x3(export));
1196 #if WITH_AFB_HOOK
1197                 else {
1198                         afb_hook_api_on_event_handler_before(export, event, eventid, object, handler->pattern);
1199                         callback(handler->closure, event, object, to_api_x3(export));
1200                         afb_hook_api_on_event_handler_after(export, event, eventid, object, handler->pattern);
1201                 }
1202 #endif
1203         } else {
1204                 /* transmit to default handler */
1205                 if (export->on_any_event_v3)
1206                         export->on_any_event_v3(to_api_x3(export), event, object);
1207                 else if (export->on_any_event_v12)
1208                         export->on_any_event_v12(event, object);
1209         }
1210
1211 #if WITH_AFB_HOOK
1212         /* hook the event after */
1213         if (export->hooksvc & afb_hook_flag_api_on_event)
1214                 afb_hook_api_on_event_after(export, event, eventid, object);
1215 #endif
1216         json_object_put(object);
1217 }
1218
1219 /* the interface for events */
1220 static const struct afb_evt_itf evt_itf = {
1221         .broadcast = listener_of_events,
1222         .push = listener_of_events
1223 };
1224
1225 /* ensure an existing listener */
1226 static int ensure_listener(struct afb_export *export)
1227 {
1228         if (!export->listener) {
1229                 export->listener = afb_evt_listener_create(&evt_itf, export);
1230                 if (export->listener == NULL)
1231                         return -1;
1232         }
1233         return 0;
1234 }
1235
1236 int afb_export_event_handler_add(
1237                         struct afb_export *export,
1238                         const char *pattern,
1239                         void (*callback)(void *, const char*, struct json_object*, struct afb_api_x3*),
1240                         void *closure)
1241 {
1242         int rc;
1243
1244         /* ensure the listener */
1245         rc = ensure_listener(export);
1246         if (rc < 0)
1247                 return rc;
1248
1249         /* ensure the globset for event handling */
1250         if (!export->event_handlers) {
1251                 export->event_handlers = globset_create();
1252                 if (!export->event_handlers)
1253                         goto oom_error;
1254         }
1255
1256         /* add the handler */
1257         rc = globset_add(export->event_handlers, pattern, callback, closure);
1258         if (rc == 0)
1259                 return 0;
1260
1261         if (errno == EEXIST) {
1262                 ERROR("[API %s] event handler %s already exists", export->api.apiname, pattern);
1263                 return -1;
1264         }
1265
1266 oom_error:
1267         ERROR("[API %s] can't allocate event handler %s", export->api.apiname, pattern);
1268         return -1;
1269 }
1270
1271 int afb_export_event_handler_del(
1272                         struct afb_export *export,
1273                         const char *pattern,
1274                         void **closure)
1275 {
1276         if (export->event_handlers
1277         && !globset_del(export->event_handlers, pattern, closure))
1278                 return 0;
1279
1280         ERROR("[API %s] event handler %s not found", export->api.apiname, pattern);
1281         errno = ENOENT;
1282         return -1;
1283 }
1284
1285 /******************************************************************************
1286  ******************************************************************************
1287  ******************************************************************************
1288  ******************************************************************************
1289                                            M E R G E D
1290  ******************************************************************************
1291  ******************************************************************************
1292  ******************************************************************************
1293  ******************************************************************************/
1294
1295 static void set_interfaces(struct afb_export *export)
1296 {
1297 #if WITH_AFB_HOOK
1298         export->hookditf = afb_hook_flags_api(export->api.apiname);
1299         export->hooksvc = afb_hook_flags_api(export->api.apiname);
1300         export->api.itf = export->hookditf|export->hooksvc ? &hooked_api_x3_itf : &api_x3_itf;
1301
1302         switch (export->version) {
1303 #if defined(WITH_LEGACY_BINDING_V1)
1304         case Api_Version_1:
1305                 export->export.v1.daemon.itf = export->hookditf ? &hooked_daemon_itf : &daemon_itf;
1306                 break;
1307 #endif
1308         case Api_Version_2:
1309                 export->export.v2->daemon.itf = export->hookditf ? &hooked_daemon_itf : &daemon_itf;
1310                 export->export.v2->service.itf = export->hooksvc ? &hooked_service_itf : &service_itf;
1311                 break;
1312         }
1313 #else
1314
1315         export->api.itf = &api_x3_itf;
1316
1317         switch (export->version) {
1318 #if defined(WITH_LEGACY_BINDING_V1)
1319         case Api_Version_1:
1320                 export->export.v1.daemon.itf = &daemon_itf;
1321                 break;
1322 #endif
1323         case Api_Version_2:
1324                 export->export.v2->daemon.itf = &daemon_itf;
1325                 export->export.v2->service.itf = &service_itf;
1326                 break;
1327         }
1328
1329 #endif
1330 }
1331
1332 static struct afb_export *create(
1333                                 struct afb_apiset *declare_set,
1334                                 struct afb_apiset *call_set,
1335                                 const char *apiname,
1336                                 const char *path,
1337                                 enum afb_api_version version)
1338 {
1339         struct afb_export *export;
1340         size_t lenapi;
1341
1342         /* session shared with other exports */
1343         if (common_session == NULL) {
1344                 common_session = afb_session_create (0);
1345                 if (common_session == NULL)
1346                         return NULL;
1347         }
1348         lenapi = strlen(apiname);
1349         export = calloc(1, sizeof *export + lenapi + (path == apiname || !path ? 0 : strlen(path)));
1350         if (!export)
1351                 errno = ENOMEM;
1352         else {
1353                 export->refcount = 1;
1354                 strcpy(export->name, apiname);
1355                 export->api.apiname = export->name;
1356                 if (path == apiname)
1357                         export->path = export->name;
1358                 else if (path)
1359                         export->path = strcpy(&export->name[lenapi + 1], path);
1360                 export->version = version;
1361                 export->state = Api_State_Pre_Init;
1362                 export->session = afb_session_addref(common_session);
1363                 export->declare_set = afb_apiset_addref(declare_set);
1364                 export->call_set = afb_apiset_addref(call_set);
1365         }
1366         return export;
1367 }
1368
1369 struct afb_export *afb_export_addref(struct afb_export *export)
1370 {
1371         if (export)
1372                 __atomic_add_fetch(&export->refcount, 1, __ATOMIC_RELAXED);
1373         return export;
1374 }
1375
1376 void afb_export_unref(struct afb_export *export)
1377 {
1378         if (export && !__atomic_sub_fetch(&export->refcount, 1, __ATOMIC_RELAXED))
1379                 afb_export_destroy(export);
1380 }
1381
1382 void afb_export_destroy(struct afb_export *export)
1383 {
1384         if (export) {
1385                 if (export->event_handlers)
1386                         globset_destroy(export->event_handlers);
1387                 if (export->listener != NULL)
1388                         afb_evt_listener_unref(export->listener);
1389                 afb_session_unref(export->session);
1390                 afb_apiset_unref(export->declare_set);
1391                 afb_apiset_unref(export->call_set);
1392                 json_object_put(export->settings);
1393                 afb_export_unref(export->creator);
1394                 if (export->api.apiname != export->name)
1395                         free((void*)export->api.apiname);
1396                 free(export);
1397         }
1398 }
1399
1400 struct afb_export *afb_export_create_none_for_path(
1401                         struct afb_apiset *declare_set,
1402                         struct afb_apiset *call_set,
1403                         const char *path,
1404                         int (*creator)(void*, struct afb_api_x3*),
1405                         void *closure)
1406 {
1407         struct afb_export *export = create(declare_set, call_set, path, path, Api_Version_None);
1408         if (export) {
1409                 afb_export_logmask_set(export, logmask);
1410                 set_interfaces(export);
1411                 if (creator && creator(closure, to_api_x3(export)) < 0) {
1412                         afb_export_unref(export);
1413                         export = NULL;
1414                 }
1415         }
1416         return export;
1417 }
1418
1419 #if defined(WITH_LEGACY_BINDING_V1)
1420 struct afb_export *afb_export_create_v1(struct afb_apiset *declare_set,
1421                         struct afb_apiset *call_set,
1422                         const char *apiname,
1423                         int (*init)(struct afb_service_x1),
1424                         void (*onevent)(const char*, struct json_object*),
1425                         const char* path)
1426 {
1427         struct afb_export *export = create(declare_set, call_set, apiname, path, Api_Version_1);
1428         if (export) {
1429                 export->init.v1 = init;
1430                 export->on_any_event_v12 = onevent;
1431                 export->export.v1.mode = AFB_MODE_LOCAL;
1432                 export->export.v1.daemon.closure = to_api_x3(export);
1433                 afb_export_logmask_set(export, logmask);
1434                 set_interfaces(export);
1435         }
1436         return export;
1437 }
1438 #endif
1439
1440 struct afb_export *afb_export_create_v2(struct afb_apiset *declare_set,
1441                         struct afb_apiset *call_set,
1442                         const char *apiname,
1443                         const struct afb_binding_v2 *binding,
1444                         struct afb_binding_data_v2 *data,
1445                         int (*init)(),
1446                         void (*onevent)(const char*, struct json_object*),
1447                         const char* path)
1448 {
1449         struct afb_export *export = create(declare_set, call_set, apiname, path, Api_Version_2);
1450         if (export) {
1451                 export->init.v2 = init;
1452                 export->on_any_event_v12 = onevent;
1453                 export->desc.v2 = binding;
1454                 export->export.v2 = data;
1455                 data->daemon.closure = to_api_x3(export);
1456                 data->service.closure = to_api_x3(export);
1457                 afb_export_logmask_set(export, logmask);
1458                 set_interfaces(export);
1459         }
1460         return export;
1461 }
1462
1463 struct afb_export *afb_export_create_v3(struct afb_apiset *declare_set,
1464                         struct afb_apiset *call_set,
1465                         const char *apiname,
1466                         struct afb_api_v3 *apiv3,
1467                         struct afb_export* creator,
1468                         const char* path)
1469 {
1470         struct afb_export *export = create(declare_set, call_set, apiname, path, Api_Version_3);
1471         if (export) {
1472                 export->unsealed = 1;
1473                 export->desc.v3 = apiv3;
1474                 export->creator = afb_export_addref(creator);
1475                 afb_export_logmask_set(export, logmask);
1476                 set_interfaces(export);
1477         }
1478         return export;
1479 }
1480
1481 int afb_export_add_alias(struct afb_export *export, const char *apiname, const char *aliasname)
1482 {
1483         return afb_apiset_add_alias(export->declare_set, apiname ?: export->api.apiname, aliasname);
1484 }
1485
1486 int afb_export_rename(struct afb_export *export, const char *apiname)
1487 {
1488         char *name;
1489
1490         if (export->declared) {
1491                 errno = EBUSY;
1492                 return -1;
1493         }
1494
1495         /* copy the name locally */
1496         name = strdup(apiname);
1497         if (!name) {
1498                 errno = ENOMEM;
1499                 return -1;
1500         }
1501
1502         if (export->api.apiname != export->name)
1503                 free((void*)export->api.apiname);
1504         export->api.apiname = name;
1505
1506         set_interfaces(export);
1507         return 0;
1508 }
1509
1510 const char *afb_export_apiname(const struct afb_export *export)
1511 {
1512         return export->api.apiname;
1513 }
1514
1515 int afb_export_unshare_session(struct afb_export *export)
1516 {
1517         if (export->session == common_session) {
1518                 export->session = afb_session_create (0);
1519                 if (export->session)
1520                         afb_session_unref(common_session);
1521                 else {
1522                         export->session = common_session;
1523                         return -1;
1524                 }
1525         }
1526         return 0;
1527 }
1528
1529 int afb_export_handle_events_v12(struct afb_export *export, void (*on_event)(const char *event, struct json_object *object))
1530 {
1531         /* check version */
1532         switch (export->version) {
1533 #if defined(WITH_LEGACY_BINDING_V1)
1534         case Api_Version_1:
1535 #endif
1536         case Api_Version_2:
1537                 break;
1538         default:
1539                 ERROR("invalid version 12 for API %s", export->api.apiname);
1540                 errno = EINVAL;
1541                 return -1;
1542         }
1543
1544         export->on_any_event_v12 = on_event;
1545         return ensure_listener(export);
1546 }
1547
1548 int afb_export_handle_events_v3(struct afb_export *export, void (*on_event)(struct afb_api_x3 *api, const char *event, struct json_object *object))
1549 {
1550         /* check version */
1551         switch (export->version) {
1552         case Api_Version_3: break;
1553         default:
1554                 ERROR("invalid version Dyn for API %s", export->api.apiname);
1555                 errno = EINVAL;
1556                 return -1;
1557         }
1558
1559         export->on_any_event_v3 = on_event;
1560         return ensure_listener(export);
1561 }
1562
1563 int afb_export_handle_init_v3(struct afb_export *export, int (*oninit)(struct afb_api_x3 *api))
1564 {
1565         if (export->state != Api_State_Pre_Init) {
1566                 ERROR("[API %s] Bad call to 'afb_api_x3_on_init', must be in PreInit", export->api.apiname);
1567                 errno = EINVAL;
1568                 return -1;
1569         }
1570
1571         export->init.v3  = oninit;
1572         return 0;
1573 }
1574
1575 #if defined(WITH_LEGACY_BINDING_V1)
1576 /*
1577  * Starts a new service (v1)
1578  */
1579 struct afb_binding_v1 *afb_export_register_v1(struct afb_export *export, struct afb_binding_v1 *(*regfun)(const struct afb_binding_interface_v1*))
1580 {
1581         return export->desc.v1 = regfun(&export->export.v1);
1582 }
1583 #endif
1584
1585 int afb_export_preinit_x3(
1586                 struct afb_export *export,
1587                 int (*preinit)(void*, struct afb_api_x3*),
1588                 void *closure)
1589 {
1590         return preinit(closure, to_api_x3(export));
1591 }
1592
1593 int afb_export_logmask_get(const struct afb_export *export)
1594 {
1595         return export->api.logmask;
1596 }
1597
1598 void afb_export_logmask_set(struct afb_export *export, int mask)
1599 {
1600         export->api.logmask = mask;
1601         switch (export->version) {
1602 #if defined(WITH_LEGACY_BINDING_V1)
1603         case Api_Version_1: export->export.v1.verbosity = verbosity_from_mask(mask); break;
1604 #endif
1605         case Api_Version_2: export->export.v2->verbosity = verbosity_from_mask(mask); break;
1606         }
1607 }
1608
1609 void *afb_export_userdata_get(const struct afb_export *export)
1610 {
1611         return export->api.userdata;
1612 }
1613
1614 void afb_export_userdata_set(struct afb_export *export, void *data)
1615 {
1616         export->api.userdata = data;
1617 }
1618
1619 /******************************************************************************
1620  ******************************************************************************
1621  ******************************************************************************
1622  ******************************************************************************
1623                                            N E W
1624  ******************************************************************************
1625  ******************************************************************************
1626  ******************************************************************************
1627  ******************************************************************************/
1628
1629 struct init
1630 {
1631         int return_code;
1632         struct afb_export *export;
1633 };
1634
1635 static void do_init(int sig, void *closure)
1636 {
1637         int rc = -1;
1638         struct init *init = closure;
1639         struct afb_export *export;
1640
1641         if (sig)
1642                 errno = EFAULT;
1643         else {
1644                 export = init->export;
1645                 switch (export->version) {
1646 #if defined(WITH_LEGACY_BINDING_V1)
1647                 case Api_Version_1:
1648                         rc = export->init.v1 ? export->init.v1(
1649                                 (struct afb_service_x1){
1650 #if WITH_AFB_HOOK
1651                                         .itf = &hooked_service_itf,
1652 #else
1653                                         .itf = &service_itf,
1654 #endif
1655                                         .closure = to_api_x3(export) }) : 0;
1656                         break;
1657 #endif
1658                 case Api_Version_2:
1659                         rc = export->init.v2 ? export->init.v2() : 0;
1660                         break;
1661                 case Api_Version_3:
1662                         rc = export->init.v3 ? export->init.v3(to_api_x3(export)) : 0;
1663                         break;
1664                 default:
1665                         errno = EINVAL;
1666                         break;
1667                 }
1668         }
1669         init->return_code = rc;
1670 };
1671
1672
1673 int afb_export_start(struct afb_export *export)
1674 {
1675         struct init init;
1676         int rc;
1677
1678         /* check state */
1679         switch (export->state) {
1680         case Api_State_Run:
1681                 return 0;
1682
1683         case Api_State_Init:
1684                 /* starting in progress: it is an error */
1685                 ERROR("Service of API %s required started while starting", export->api.apiname);
1686                 return -1;
1687
1688         default:
1689                 break;
1690         }
1691
1692         /* set event handling */
1693         switch (export->version) {
1694 #if defined(WITH_LEGACY_BINDING_V1)
1695         case Api_Version_1:
1696 #endif
1697         case Api_Version_2:
1698                 if (export->on_any_event_v12) {
1699                         rc = afb_export_handle_events_v12(export, export->on_any_event_v12);
1700                         break;
1701                 }
1702                 /*@fallthrough@*/
1703         default:
1704                 rc = 0;
1705                 break;
1706         }
1707         if (rc < 0) {
1708                 ERROR("Can't set event handler for %s", export->api.apiname);
1709                 return -1;
1710         }
1711
1712 #if WITH_AFB_HOOK
1713         /* Starts the service */
1714         if (export->hooksvc & afb_hook_flag_api_start)
1715                 afb_hook_api_start_before(export);
1716 #endif
1717
1718         export->state = Api_State_Init;
1719         init.export = export;
1720         sig_monitor(0, do_init, &init);
1721         rc = init.return_code;
1722         export->state = Api_State_Run;
1723
1724 #if WITH_AFB_HOOK
1725         if (export->hooksvc & afb_hook_flag_api_start)
1726                 afb_hook_api_start_after(export, rc);
1727 #endif
1728
1729         if (rc < 0) {
1730                 /* initialisation error */
1731                 ERROR("Initialisation of service API %s failed (%d): %m", export->api.apiname, rc);
1732                 return rc;
1733         }
1734
1735         return 0;
1736 }
1737
1738 static void api_call_cb(void *closure, struct afb_xreq *xreq)
1739 {
1740         struct afb_export *export = closure;
1741
1742         xreq->request.api = to_api_x3(export);
1743
1744         switch (export->version) {
1745 #if defined(WITH_LEGACY_BINDING_V1)
1746         case Api_Version_1:
1747                 afb_api_so_v1_process_call(export->desc.v1, xreq);
1748                 break;
1749 #endif
1750         case Api_Version_2:
1751                 afb_api_so_v2_process_call(export->desc.v2, xreq);
1752                 break;
1753         case Api_Version_3:
1754                 afb_api_v3_process_call(export->desc.v3, xreq);
1755                 break;
1756         default:
1757                 afb_xreq_reply(xreq, NULL, "bad-api-type", NULL);
1758                 break;
1759         }
1760 }
1761
1762 static struct json_object *api_describe_cb(void *closure)
1763 {
1764         struct afb_export *export = closure;
1765         struct json_object *result;
1766
1767         switch (export->version) {
1768 #if defined(WITH_LEGACY_BINDING_V1)
1769         case Api_Version_1:
1770                 result = afb_api_so_v1_make_description_openAPIv3(export->desc.v1, export->api.apiname);
1771                 break;
1772 #endif
1773         case Api_Version_2:
1774                 result = afb_api_so_v2_make_description_openAPIv3(export->desc.v2, export->api.apiname);
1775                 break;
1776         case Api_Version_3:
1777                 result = afb_api_v3_make_description_openAPIv3(export->desc.v3, export->api.apiname);
1778                 break;
1779         default:
1780                 result = NULL;
1781                 break;
1782         }
1783         return result;
1784 }
1785
1786 static int api_service_start_cb(void *closure)
1787 {
1788         struct afb_export *export = closure;
1789
1790         return afb_export_start(export);
1791 }
1792
1793 #if WITH_AFB_HOOK
1794 static void api_update_hooks_cb(void *closure)
1795         __attribute__((alias("set_interfaces")));
1796
1797 void afb_export_update_hooks(struct afb_export *export)
1798         __attribute__((alias("set_interfaces")));
1799 #endif
1800
1801 static int api_get_logmask_cb(void *closure)
1802 {
1803         struct afb_export *export = closure;
1804
1805         return afb_export_logmask_get(export);
1806 }
1807
1808 static void api_set_logmask_cb(void *closure, int level)
1809 {
1810         struct afb_export *export = closure;
1811
1812         afb_export_logmask_set(export, level);
1813 }
1814
1815 static void api_unref_cb(void *closure)
1816 {
1817         struct afb_export *export = closure;
1818
1819         afb_export_unref(export);
1820 }
1821
1822 static struct afb_api_itf export_api_itf =
1823 {
1824         .call = api_call_cb,
1825         .service_start = api_service_start_cb,
1826 #if WITH_AFB_HOOK
1827         .update_hooks = api_update_hooks_cb,
1828 #endif
1829         .get_logmask = api_get_logmask_cb,
1830         .set_logmask = api_set_logmask_cb,
1831         .describe = api_describe_cb,
1832         .unref = api_unref_cb
1833 };
1834
1835 int afb_export_declare(struct afb_export *export,
1836                         int noconcurrency)
1837 {
1838         int rc;
1839         struct afb_api_item afb_api;
1840
1841         if (export->declared)
1842                 rc = 0;
1843         else {
1844                 /* init the record structure */
1845                 afb_api.closure = afb_export_addref(export);
1846                 afb_api.itf = &export_api_itf;
1847                 afb_api.group = noconcurrency ? export : NULL;
1848
1849                 /* records the binding */
1850                 rc = afb_apiset_add(export->declare_set, export->api.apiname, afb_api);
1851                 if (rc >= 0)
1852                         export->declared = 1;
1853                 else {
1854                         ERROR("can't declare export %s to set %s, ABORTING it!",
1855                                 export->api.apiname,
1856                                 afb_apiset_name(export->declare_set));
1857                         afb_export_unref(export);
1858                 }
1859         }
1860
1861         return rc;
1862 }
1863
1864 void afb_export_undeclare(struct afb_export *export)
1865 {
1866         if (export->declared) {
1867                 export->declared = 0;
1868                 afb_apiset_del(export->declare_set, export->api.apiname);
1869         }
1870 }
1871
1872 int afb_export_subscribe(struct afb_export *export, struct afb_event_x2 *event)
1873 {
1874         return afb_evt_event_x2_add_watch(export->listener, event);
1875 }
1876
1877 int afb_export_unsubscribe(struct afb_export *export, struct afb_event_x2 *event)
1878 {
1879         return afb_evt_event_x2_remove_watch(export->listener, event);
1880 }
1881
1882 void afb_export_process_xreq(struct afb_export *export, struct afb_xreq *xreq)
1883 {
1884         afb_xreq_process(xreq, export->call_set);
1885 }
1886
1887 void afb_export_context_init(struct afb_export *export, struct afb_context *context)
1888 {
1889         afb_context_init(context, export->session, NULL);
1890         context->validated = 1;
1891 }
1892