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