afm-launch: begins integration of modes
authorJosé Bollo <jose.bollo@iot.bzh>
Sat, 13 Feb 2016 16:20:08 +0000 (17:20 +0100)
committerJosé Bollo <jose.bollo@iot.bzh>
Sat, 13 Feb 2016 16:20:08 +0000 (17:20 +0100)
Change-Id: I51b3659ca86c04f7276b4beb0e0863fa0e1d700d
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
conf/afm-launch.conf
src/afm-launch.c
src/afm-user-daemon.c

index a572c88..92ede4d 100644 (file)
@@ -14,6 +14,8 @@
 # %H height
 # %% %
 
+mode local
+
 text/html
        /usr/bin/afb-daemon --alias=/icons:%I --port=%P --rootdir=%r --token=%S --sessiondir=%D/.afb-daemon
        /usr/bin/web-runtime http://localhost:%P/%c?token=%S
@@ -24,3 +26,9 @@ application/x-executable
 text/vnd.qt.qml
        /usr/bin/qt5/qmlscene -fullscreen -I %r -I %r/imports %r/%c
 
+mode remote
+
+text/html
+       /usr/bin/afb-daemon --alias=/icons:%I --port=%P --rootdir=%r --token=%S --sessiondir=%D/.afb-daemon
+       http://%%h:%P/%c?token=%S
+
index 216e6df..87e8e3a 100644 (file)
@@ -38,20 +38,18 @@ extern char **environ;
 
 #define DEFAULT_TYPE "text/html"
 
-const char separators[] = " \t\n";
-
-struct execdesc {
-       char *type;
-       char **execs[2];
+struct type_list {
+       struct type_list *next;
+       char type[1];
 };
 
-struct launchers {
-       int count;
-       struct execdesc *descs;
+struct desc_list {
+       struct desc_list *next;
+       enum afm_launch_mode mode;
+       struct type_list *types;
+       char **execs[2];
 };
 
-static struct launchers launchers = { 0, NULL };
-
 struct launchparam {
        int port;
        const char *secret;
@@ -60,8 +58,6 @@ struct launchparam {
        const char **slave;
 };
 
-static gid_t groupid = 0;
-
 struct confread {
        const char *filepath;
        FILE *file;
@@ -71,17 +67,29 @@ struct confread {
        char buffer[4096];
 };
 
-static void dump_launchers(struct launchers *launchs)
+struct desc_list *launchers = NULL;
+
+static gid_t groupid = 0;
+
+const char separators[] = " \t\n";
+
+static void dump_launchers()
 {
-       int i, j, k;
-       for (i = 0 ; i < launchs->count ; i++) {
-               printf("%s\n", launchs->descs[i].type);
+       int j, k;
+       struct desc_list *desc;
+       struct type_list *type;
+
+       for (desc = launchers ; desc != NULL ; desc = desc->next) {
+               printf("mode %s\n", name_of_launch_mode(desc->mode));
+               for (type = desc->types ; type != NULL ; type = type->next)
+                       printf("%s\n", type->type);
                for ( j = 0 ; j < 2 ; j++)
-                       if (launchs->descs[i].execs[j] != NULL) {
-                               for (k = 0 ; launchs->descs[i].execs[j][k] != NULL ; k++)
-                                       printf("  %s", launchs->descs[i].execs[j][k]);
+                       if (desc->execs[j] != NULL) {
+                               for (k = 0 ; desc->execs[j][k] != NULL ; k++)
+                                       printf("  %s", desc->execs[j][k]);
                                printf("\n");
                        }
+               printf("\n");
        }
 }
 
@@ -110,13 +118,7 @@ static int read_line(struct confread *cread)
        return 0;
 }
 
-static char *dup_token(struct confread *cread)
-{
-       assert(cread->length);
-       return strndup(&cread->buffer[cread->index], cread->length);
-}
-
-static char **dup_tokens_vector(struct confread *cread)
+static char **read_vector(struct confread *cread)
 {
        int index0, length0;
        char **vector, *args;
@@ -158,99 +160,171 @@ static char **dup_tokens_vector(struct confread *cread)
        return vector;
 }
 
-static int read_type(struct confread *cread)
+static struct type_list *read_type(struct confread *cread)
 {
-       int count;
-       struct execdesc *descs;
-       char *type;
+       int index, length;
+       struct type_list *result;
 
-       /* get the type */
-       type = dup_token(cread);
-       if (type == NULL) {
-               ERROR("%s:%d: out of memory", cread->filepath, cread->lineno);
-               errno = ENOMEM;
-               return -1;
-       }
+       /* record index and length */
+       index = cread->index;
+       length = cread->length;
 
-       /* check the type */
+       /* check no extra characters */
        if (next_token(cread)) {
-               ERROR("%s:%d: extra characters found after type %s", cread->filepath, cread->lineno, type);
-               free(type);
+               ERROR("%s:%d: extra characters found after type %.*s", cread->filepath, cread->lineno, length, &cread->buffer[index]);
                errno = EINVAL;
-               return -1;
+               return NULL;
        }
 
-       /* allocates data */
-       count = launchers.count + 1;
-       descs = realloc(launchers.descs, count * sizeof(struct execdesc));
-       if (descs == NULL) {
-               free(type);
+       /* allocate structure */
+       result = malloc(sizeof(struct type_list) + length);
+       if (result == NULL) {
+               ERROR("%s:%d: out of memory", cread->filepath, cread->lineno);
                errno = ENOMEM;
-               return -1;
+               return NULL;
        }
 
-       /* fill data */
-       launchers.descs = descs;
-       descs += count - 1;
-       descs->type = type;
-       descs->execs[0] = NULL;
-       descs->execs[1] = NULL;
-       launchers.count = count;
-       return 0;
+       /* fill the structure */
+       memcpy(result->type, &cread->buffer[index], length);
+       result->type[length] = 0;
+       return result;
 }
 
-static int read_args(struct confread *cread, int bottom, int offset)
+static enum afm_launch_mode read_mode(struct confread *cread)
 {
-       char **vector;
+       int index, length;
+       enum afm_launch_mode result;
 
-       while (bottom < launchers.count) {
-               vector = dup_tokens_vector(cread);
-               if (vector == NULL) {
-                       ERROR("%s:%d: out of memory", cread->filepath, cread->lineno);
-                       return -1;
-               }
-               launchers.descs[bottom++].execs[offset] = vector;
+       assert(cread->index == 0);
+       assert(!strncmp(&cread->buffer[cread->index], "mode", 4));
+
+       /* get the next token: the mode string */
+       if (!next_token(cread)) {
+               ERROR("%s:%d: no mode value set", cread->filepath, cread->lineno);
+               errno = EINVAL;
+               return invalid_launch_mode;
+       }
+
+       /* record index and length */
+       index = cread->index;
+       length = cread->length;
+
+       /* check no extra characters */
+       if (next_token(cread)) {
+               ERROR("%s:%d: extra characters found after mode %.*s", cread->filepath, cread->lineno, length, &cread->buffer[index]);
+               errno = EINVAL;
+               return invalid_launch_mode;
+       }
+
+       /* get the mode */
+       cread->buffer[index + length] = 0;
+       result = launch_mode_of_string(&cread->buffer[index]);
+       if (result == invalid_launch_mode) {
+               ERROR("%s:%d: invalid mode value %s", cread->filepath, cread->lineno, &cread->buffer[index]);
+               errno = EINVAL;
+       }
+       return result;
+}
+
+static void free_type_list(struct type_list *types)
+{
+       while (types != NULL) {
+               struct type_list *next = types->next;
+               free(types);
+               types = next;
        }
-       return 0;
 }
 
 static int read_launchers(struct confread *cread)
 {
-       int rc, bottom, offset, typed;
+       int rc;
+       struct type_list *types, *lt;
+       struct desc_list *desc;
+       enum afm_launch_mode mode;
+       char **vector;
 
        /* reads the file */
-       offset = 0;
-       typed = 0;
-       bottom = launchers.count;
+       lt = NULL;
+       types = NULL;
+       desc = NULL;
+       mode = invalid_launch_mode;
        rc = read_line(cread);
        while (rc > 0) {
                if (cread->index == 0) {
-                       if (!typed)
-                               bottom = launchers.count;
-                       rc = read_type(cread);
-                       if (rc)
-                               return rc;
-                       if (!typed) {
-                               typed = 1;
-                               offset = 0;
+                       if (cread->length == 4 && !memcmp(&cread->buffer[cread->index], "mode", 4)) {
+                               /* check if allowed */
+                               if (types != NULL) {
+                                       ERROR("%s:%d: mode found before launch vector", cread->filepath, cread->lineno);
+                                       errno = EINVAL;
+                                       free_type_list(types);
+                                       return -1;
+                               }
+
+                               /* read the mode */
+                               mode = read_mode(cread);
+                               if (mode == invalid_launch_mode)
+                                       return -1;
+                       } else {
+                               if (mode == invalid_launch_mode) {
+                                       ERROR("%s:%d: mode not found before type", cread->filepath, cread->lineno);
+                                       errno = EINVAL;
+                                       assert(types == NULL);
+                                       return -1;
+                               }
+                               /* read a type */
+                               lt = read_type(cread);
+                               if (lt == NULL) {
+                                       free_type_list(types);
+                                       return -1;
+                               }
+                               lt->next = types;
+                               types = lt;
                        }
-               } else if (!typed && !offset) {
-                       ERROR("%s:%d: untyped launcher found", cread->filepath, cread->lineno);
-                       errno = EINVAL;
-                       return -1;
-               } else if (offset >= 2) {
-                       ERROR("%s:%d: extra launcher found", cread->filepath, cread->lineno);
+                       desc = NULL;
+               } else if (types == NULL && desc == NULL) {
+                       if (lt == NULL)
+                               ERROR("%s:%d: untyped launch vector found", cread->filepath, cread->lineno);
+                       else
+                               ERROR("%s:%d: extra launch vector found (2 max)", cread->filepath, cread->lineno);
                        errno = EINVAL;
                        return -1;
                } else {
-                       rc = read_args(cread, bottom, offset);
-                       if (rc)
-                               return rc;
-                       offset++;
-                       typed = 0;
+                       vector = read_vector(cread);
+                       if (vector == NULL) {
+                               ERROR("%s:%d: out of memory", cread->filepath, cread->lineno);
+                               free_type_list(types);
+                               errno = ENOMEM;
+                               return -1;
+                       }
+                       if (types) {
+                               assert(desc == NULL);
+                               desc = malloc(sizeof * desc);
+                               if (desc == NULL) {
+                                       ERROR("%s:%d: out of memory", cread->filepath, cread->lineno);
+                                       free_type_list(types);
+                                       errno = ENOMEM;
+                                       return -1;
+                               }
+                               desc->next = launchers;
+                               desc->mode = mode;
+                               desc->types = types;
+                               desc->execs[0] = vector;
+                               desc->execs[1] = NULL;
+                               types = NULL;
+                               launchers = desc;
+                       } else {
+                               desc->execs[1] = vector;
+                               desc = NULL;
+                       }
                }
                rc = read_line(cread);
        }
+       if (types != NULL) {
+               ERROR("%s:%d: end of file found before launch vector", cread->filepath, cread->lineno);
+               free_type_list(types);
+               errno = EINVAL;
+               return -1;
+       }
        return rc;
 }
 
@@ -587,17 +661,31 @@ int afm_launch_initialize()
                groupid = -1;
 
        rc = read_configuration_file(FWK_LAUNCH_CONF);
-       dump_launchers(&launchers);
+       dump_launchers();
        return rc;
 }
 
+static struct desc_list *search_launcher(const char *type, enum afm_launch_mode mode)
+{
+       struct desc_list *dl;
+       struct type_list *tl;
+
+       for (dl = launchers ; dl ; dl = dl->next)
+               if (dl->mode == mode)
+                       for (tl = dl->types ; tl != NULL ; tl = tl->next)
+                               if (!strcmp(tl->type, type))
+                                       return dl;
+       return NULL;
+}
+
 int afm_launch(struct afm_launch_desc *desc, pid_t children[2], char **uri)
 {
        char datadir[PATH_MAX];
-       int ikl, rc;
+       int rc;
        char secret[9];
        struct launchparam params;
        const char *type;
+       struct desc_list *dl;
 
        /* should be init */
        assert(groupid != 0);
@@ -609,11 +697,9 @@ int afm_launch(struct afm_launch_desc *desc, pid_t children[2], char **uri)
 
        /* what launcher ? */
        type = desc->type != NULL && *desc->type ? desc->type : DEFAULT_TYPE;
-       ikl = 0;
-       while (ikl < launchers.count && strcmp(type, launchers.descs[ikl].type))
-               ikl++;
-       if (ikl == launchers.count) {
-               ERROR("type %s not found!", type);
+       dl = search_launcher(type, desc->mode);
+       if (dl == NULL) {
+               ERROR("type %s not found for mode %s!", type, name_of_launch_mode(desc->mode));
                errno = ENOENT;
                return -1;
        }
@@ -631,8 +717,8 @@ int afm_launch(struct afm_launch_desc *desc, pid_t children[2], char **uri)
        params.port = mkport();
        params.secret = secret;
        params.datadir = datadir;
-       params.master = (const char **)launchers.descs[ikl].execs[0];
-       params.slave = (const char **)launchers.descs[ikl].execs[1];
+       params.master = (const char **)dl->execs[0];
+       params.slave = (const char **)dl->execs[1];
 
        return params.slave ? launchexec2(desc, children, &params) : launchexec1(desc, children, &params);
 }
index 09ec0b5..81115d7 100644 (file)
@@ -140,7 +140,7 @@ static void on_start(struct jreq *jreq, struct json_object *obj)
        }
 
        /* get the application */
-       INFO("method start called for %s mode=%s", appid, mode);
+       INFO("method start called for %s mode=%s", appid, name_of_launch_mode(mode));
        appli = afm_db_get_application(afdb, appid);
        if (appli == NULL) {
                jbus_reply_error_s(jreq, error_not_found);