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