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