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