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