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