summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2017-03-17 17:03:01 +0100
committerJosé Bollo <jose.bollo@iot.bzh>2017-03-17 17:49:22 +0100
commita069be3d476bbdaa56ce4750c8868b4f0682564a (patch)
tree04bef2b66ddb212dbaa84e426f1e95b9589c7c7b
parentb6afa1aa893544b459cb767cc5a2ad8d2148228c (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.md33
-rw-r--r--src/wgtpkg-install.c65
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();