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