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