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