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