X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-api-so-v2.c;h=120747465d9df3cb03b5dd4c12732cf50634d537;hb=f2995647f0f79e816c7f46033e1ec824185732b5;hp=d56c9852a77c309c76410a535fc575da0f02cb3a;hpb=05e0214d821f1a7604b4a0897907f347761b56e6;p=src%2Fapp-framework-binder.git diff --git a/src/afb-api-so-v2.c b/src/afb-api-so-v2.c index d56c9852..12074746 100644 --- a/src/afb-api-so-v2.c +++ b/src/afb-api-so-v2.c @@ -34,6 +34,7 @@ #include "afb-context.h" #include "afb-api-so.h" #include "afb-xreq.h" +#include "afb-perm.h" #include "verbose.h" /* @@ -41,6 +42,14 @@ */ static const char afb_api_so_v2_descriptor[] = "afbBindingV2"; +/** + * structure for memorizing verbs sorted with permissions + */ +struct verb_v2 { + const struct afb_verb_v2 *verb; + struct afb_perm *perm; +}; + /* * Description of a binding */ @@ -49,16 +58,29 @@ struct api_so_v2 { void *handle; /* context of dlopen */ struct afb_svc *service; /* handler for service started */ struct afb_ditf ditf; /* daemon interface */ + int count; + struct verb_v2 verbs[1]; }; static const struct afb_verb_v2 *search(struct api_so_v2 *desc, const char *verb) { - const struct afb_verb_v2 *result; - - result = desc->binding->verbs; - while (result->verb && strcasecmp(result->verb, verb)) - result++; - return result->verb ? result : NULL; + const struct afb_verb_v2 *v; + int i, l, u, c; + + l = 0; + u = desc->count; + while (l < u) { + i = (l + u) >> 1; + v = desc->verbs[i].verb; + c = strcasecmp(v->verb, verb); + if (c == 0) + return v; + if (c < 0) + l = i + 1; + else + u = i; + } + return NULL; } static void call_cb(void *closure, struct afb_xreq *xreq) @@ -155,20 +177,55 @@ int afb_api_so_v2_add_binding(const struct afb_binding_v2 *binding, void *handle int rc; struct api_so_v2 *desc; struct afb_api afb_api; + const struct afb_verb_v2 *bv; + int count, i, j; /* basic checks */ assert(binding->api); assert(binding->specification); assert(binding->verbs); + /* count the verbs */ + count = 0; + while (binding->verbs[count].verb) + count++; + /* allocates the description */ - desc = calloc(1, sizeof *desc); + desc = malloc(sizeof *desc + (count - 1) * sizeof desc->verbs); if (desc == NULL) { ERROR("out of memory"); goto error; } desc->binding = binding; desc->handle = handle; + desc->service = NULL; + memset(&desc->ditf, 0, sizeof desc->ditf); + desc->count = count; + + /* fill the verbs sorted */ + for (i = 0 ; i < count ; i++) { + desc->verbs[i].perm = NULL; + j = i; + bv = &binding->verbs[j]; + while (j && strcasecmp(bv->verb, desc->verbs[j-1].verb->verb) < 0) { + desc->verbs[j].verb = desc->verbs[j-1].verb; + j--; + } + desc->verbs[j].verb = bv; + } + + /* makes the permissions */ + for (i = 0 ; i < count ; i++) { + if (desc->verbs[i].verb->permissions) { + desc->verbs[i].perm = afb_perm_parse(desc->verbs[i].verb->permissions); + if (!desc->verbs[i].perm) { + ERROR("Bad permission specification for verb %s of api %s: %s", + desc->verbs[i].verb->verb, binding->api, + desc->verbs[i].verb->permissions); + goto error2; + } + } + } /* init the interface */ afb_ditf_init(&desc->ditf, binding->api); @@ -194,6 +251,10 @@ int afb_api_so_v2_add_binding(const struct afb_binding_v2 *binding, void *handle return 1; error2: + count = desc->count; + while (count) + if (desc->verbs[--count].perm) + afb_perm_unref(desc->verbs[count].perm); free(desc); error: return -1;