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