diff options
author | José Bollo <jose.bollo@iot.bzh> | 2017-03-17 17:03:01 +0100 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2017-03-17 17:49:22 +0100 |
commit | a069be3d476bbdaa56ce4750c8868b4f0682564a (patch) | |
tree | 04bef2b66ddb212dbaa84e426f1e95b9589c7c7b | |
parent | b6afa1aa893544b459cb767cc5a2ad8d2148228c (diff) |
wgtpkg-install: choose the port
The installer now chooses a port for an installed application.
This choose is made by consulting the previously installed
applications and by getting the lowest port available in the
range 1024..32767.
Change-Id: Iab4238b4d52447a2d261d87d45bbb02f0b7a35e5
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-rw-r--r-- | docs/permissions.md | 33 | ||||
-rw-r--r-- | src/wgtpkg-install.c | 65 |
2 files changed, 83 insertions, 15 deletions
diff --git a/docs/permissions.md b/docs/permissions.md index 407fdc2..09f68a3 100644 --- a/docs/permissions.md +++ b/docs/permissions.md @@ -14,15 +14,15 @@ framework to keep installed permissions in a database. The permission names are [URN][URN] of the form: - urn:AGL:permission:<api>:<level>:<hierarchical-name> + urn:AGL:permission:<api>:<level>:<hierarchical-name> where "AGL" is the NID (the namespace identifier) dedicated to AGL (note: a RFC should be produced to standardize this name space). The permission names are made of NSS (the namespace specific string) starting with "permission:" and followed by colon separated -fields. The 2 first fields are <api> and <level> and the remaining -fields are grouped to form the <hierarchical-name>. +fields. The 2 first fields are `<api>` and `<level>` and the remaining +fields are grouped to form the `<hierarchical-name>`. <api> ::= [ <pname> ] @@ -32,30 +32,35 @@ fields are grouped to form the <hierarchical-name>. <extra> ::= "-" | "." | "_" | "@" -The field <api> can be made of any valid character for NSS except +The field `<api>` can be made of any valid character for NSS except the characters colon and star (:*). This field designates the api providing the permission. This scheme is used to deduce binding requirements -from permission requirements. The field <api> can be the empty +from permission requirements. The field `<api>` can be the empty string when the permission is defined by the AGL system itself. -The field <api> if starting with the character "@" represents +The field `<api>` if starting with the character "@" represents a transversal/cross permission not bound to any binding. <level> ::= 1*<lower> -The field <level> is made only of letters in lower case. -The field <level> can only take some predefined values: -"system", "platform", "partner", "tiers", "owner", "public". +The field `<level>` is made only of letters in lower case. +The field `<level>` can only take some predefined values: + + - system + - platform + - partner + - tiers + - owner + - public + +The field `<hierarchical-name>` is made of `<pname>` separated +by colons. <hierarchical-name> ::= <pname> 0*(":" <pname>) -The field <hierarchical-name> is made <pname> separated by -colons. The names at left are hierarchically grouping the +The names at left are hierarchically grouping the names at right. This hierarchical behaviour is intended to be used to request permissions using hierarchical grouping. -Permission's level ------------------- - [URN]: https://tools.ietf.org/rfc/rfc2141.txt "RFC 2141: URN Syntax" diff --git a/src/wgtpkg-install.c b/src/wgtpkg-install.c index 836b136..22b8050 100644 --- a/src/wgtpkg-install.c +++ b/src/wgtpkg-install.c @@ -25,6 +25,8 @@ #include <assert.h> #include <unistd.h> #include <stdio.h> +#include <stdlib.h> +#include <stdint.h> #include <sys/stat.h> #include "verbose.h" @@ -40,12 +42,68 @@ #include "secmgr-wrap.h" #include "utils-dir.h" #include "wgtpkg-unit.h" +#include "utils-systemd.h" +#include "utils-file.h" static const char* exec_type_strings[] = { "application/x-executable", "application/vnd.agl.native" }; +static const char key_http_port[] = "X-AFM--http-port"; + +static int get_port_cb(void *closure, const char *name, const char *path, int isuser) +{ + char *iter; + char *content; + size_t length; + int rc, p; + + /* reads the file */ + rc = getfile(path, &content, &length); + if (rc < 0) + return rc; + + /* process the file */ + iter = strstr(content, key_http_port); + while (iter) { + iter += sizeof key_http_port - 1; + while(*iter && *iter != '=' && *iter != '\n') + iter++; + if (*iter == '=') { + while(*++iter == ' '); + p = atoi(iter); + if (p >= 0 && p < 32768) + ((uint32_t*)closure)[p >> 5] |= (uint32_t)1 << (p & 31); + } + iter = strstr(iter, key_http_port); + } + free(content); + return 0; +} + +static int get_port() +{ + int rc; + uint32_t ports[1024]; /* 1024 * 32 = 32768 */ + + memset(ports, 0, sizeof ports); + rc = systemd_unit_list(0, get_port_cb, &ports); + if (rc >= 0) { + rc = systemd_unit_list(1, get_port_cb, ports); + if (rc >= 0) { + for (rc = 1024 ; rc < 32768 && !~ports[rc >> 5] ; rc += 32); + if (rc == 32768) { + errno = EADDRNOTAVAIL; + rc = -1; + } else { + while (1 & (ports[rc >> 5] >> (rc & 31))) rc++; + } + } + } + return rc; +} + static int check_defined(const void *data, const char *name) { if (data) @@ -294,6 +352,7 @@ struct wgt_info *install_widget(const char *wgtfile, const char *root, int force struct wgt_info *ifo; const struct wgt_desc *desc; char installdir[PATH_MAX]; + int port; NOTICE("-- INSTALLING widget %s to %s --", wgtfile, root); @@ -334,7 +393,11 @@ struct wgt_info *install_widget(const char *wgtfile, const char *root, int force if (install_exec_flag(desc)) goto error4; - if (unit_install(ifo, installdir, FWK_ICON_DIR, 1234/*TODO*/)) + port = get_port(); + if (port < 0) + goto error4; + + if (unit_install(ifo, installdir, FWK_ICON_DIR, port)) goto error4; file_reset(); |