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