diff options
-rw-r--r-- | conf/CMakeLists.txt | 2 | ||||
-rw-r--r-- | conf/afm-launch.conf.in | 57 | ||||
-rw-r--r-- | src/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/afm-db.c | 553 | ||||
-rw-r--r-- | src/afm-db.h | 34 | ||||
-rw-r--r-- | src/afm-launch-mode.c | 101 | ||||
-rw-r--r-- | src/afm-launch-mode.h | 32 | ||||
-rw-r--r-- | src/afm-launch.c | 959 | ||||
-rw-r--r-- | src/afm-launch.h | 38 | ||||
-rw-r--r-- | src/afm-run.c | 781 | ||||
-rw-r--r-- | src/afm-run.h | 27 | ||||
-rw-r--r-- | src/afm-system-daemon.c | 3 | ||||
-rw-r--r-- | src/afm-user-daemon.c | 169 |
13 files changed, 8 insertions, 2752 deletions
diff --git a/conf/CMakeLists.txt b/conf/CMakeLists.txt index 5f15dd6..2188dc0 100644 --- a/conf/CMakeLists.txt +++ b/conf/CMakeLists.txt @@ -18,7 +18,6 @@ cmake_minimum_required(VERSION 2.8) -configure_file(afm-launch.conf.in afm-launch.conf) configure_file(afm-unit.conf.in afm-unit.conf) configure_file(afm-unit-debug.conf.in afm-unit-debug.conf) configure_file(afm-system-daemon.service.in afm-system-daemon.service) @@ -34,7 +33,6 @@ if(NOT USE_SDK) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/afm-system-daemon.service DESTINATION ${UNITDIR_SYSTEM}) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/afm-user-daemon.conf DESTINATION ${SYSCONFDIR_DBUS_USER}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/afm-user-daemon.service DESTINATION ${UNITDIR_USER}) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/afm-launch.conf DESTINATION ${afm_confdir}) install(DIRECTORY DESTINATION ${afm_confdir}/unit.env.d) if(AGL_DEVEL) diff --git a/conf/afm-launch.conf.in b/conf/afm-launch.conf.in deleted file mode 100644 index 70083f3..0000000 --- a/conf/afm-launch.conf.in +++ /dev/null @@ -1,57 +0,0 @@ -# %% % -# %a appid -# %b bindings -# %c content -# %D datadir -# %H height -# %h homedir -# %I icondir -# %m mime-type -# %n name -# %P port -# %R readyfd -# %r rootdir -# %S secret -# %W width - -#----------------- -mode local -#----------------- - -text/html - /usr/bin/afb-daemon --mode=local --readyfd=%R --alias=/icons:%I --port=%P --rootdir=%r --roothttp=. --token=%S --sessiondir=%D/.afb-daemon - /usr/bin/web-runtime http://localhost:%P/%c?token=%S - -application/x-executable - %r/%c - -application/vnd.agl.url - /usr/bin/web-runtime %c - -application/vnd.agl.service - /usr/bin/afb-daemon --ldpaths=@CMAKE_INSTALL_FULL_LIBDIR@/afb:%r/%c --mode=local --readyfd=%R --alias=/icons:%I --port=%P --rootdir=%r --token=%S --sessiondir=%D/.afb-daemon - -application/vnd.agl.native - /usr/bin/afb-daemon --ldpaths=@CMAKE_INSTALL_FULL_LIBDIR@/afb:%r/lib --mode=local --readyfd=%R --alias=/icons:%I --port=%P --rootdir=%r --token=%S --sessiondir=%D/.afb-daemon - %r/%c %P %S - -text/vnd.qt.qml -application/vnd.agl.qml - /usr/bin/qt5/qmlscene -fullscreen -I %r -I %r/imports %r/%c - -application/vnd.agl.qml.hybrid - /usr/bin/afb-daemon --ldpaths=@CMAKE_INSTALL_FULL_LIBDIR@/afb:%r/lib --mode=local --readyfd=%R --alias=/icons:%I --port=%P --rootdir=%r --token=%S --sessiondir=%D/.afb-daemon - /usr/bin/qt5/qmlscene %P %S -fullscreen -I %r -I %r/imports %r/%c - -application/vnd.agl.html.hybrid - /usr/bin/afb-daemon --ldpaths=@CMAKE_INSTALL_FULL_LIBDIR@/afb:%r/lib --mode=local --readyfd=%R --alias=/icons:%I --port=%P --rootdir=%r --roothttp=htdocs --token=%S --sessiondir=%D/.afb-daemon - /usr/bin/web-runtime http://localhost:%P/%c?token=%S - -#----------------- -mode remote -#----------------- - -text/html - /usr/bin/afb-daemon --mode=remote --readyfd=%R --alias=/icons:%I --port=%P --rootdir=%r --roothttp=. --token=%S --sessiondir=%D/.afb-daemon - http://%%h:%P/%c?token=%S - diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3e940d1..cd3b9aa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -126,11 +126,7 @@ add_library(secwrp STATIC ) add_library(afm STATIC - afm-db.c afm-udb.c - afm-launch.c - afm-launch-mode.c - afm-run.c afm-urun.c ) diff --git a/src/afm-db.c b/src/afm-db.c deleted file mode 100644 index a15255b..0000000 --- a/src/afm-db.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - Copyright 2015, 2016, 2017 IoT.bzh - - author: José Bollo <jose.bollo@iot.bzh> - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -#include <stdlib.h> -#include <assert.h> -#include <string.h> -#include <errno.h> -#include <dirent.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/types.h> - -#include <json-c/json.h> - -#include "utils-json.h" -#include "wgt-info.h" -#include "afm-db.h" - -/* - * The json object recorded by application widget - * has the following contents: - * { - * id: STRING, the application identifier without version info - * path: STRING, the path of the root directory for the application - * content: STRING, the relative path to the entryu point of the application - * type: STRING, the mime type describing the type 'content' - * bindings: ARRAY, array of bindings - * [ - * STRING, path to the binding - * ] - * public: OBJECT, public content describing the application widget - * { - * id: STRING, the application identifier "idaver" - * version: STRING, the full version of the application - * width: INTEGER, the width indication or 0 - * height: INTEGER, the height indication or 0 - * name: STRING, the name of the application - * description: STRING, the description of the application - * shortname: STRING, the short name of the application - * author: STRING, the author of the application - * } - */ - -/* - * The structure afm_apps records the data about applications - * for several accesses. - */ -struct afm_apps { - struct json_object *pubarr; /* array of the public data of apps */ - struct json_object *direct; /* hash of applications by their "idaver" */ - struct json_object *byapp; /* hash of applications by their id */ -}; - -/* - * Two types of directory are handled: - * - root directories: contains subdirectories appid/version - * containing the applications - * - application directories: it contains an application - */ -enum dir_type { - type_root, /* type for root directory */ - type_app /* type for application directory */ -}; - -/* - * Structure for recording a path to application(s) - * in the list of directories. - */ -struct afm_db_dir { - struct afm_db_dir *next; /* link to the next item of the list */ - enum dir_type type; /* the type of the path */ - char path[1]; /* the path of the directory */ -}; - -/* - * The structure afm_db records the applications - * for a set of directories recorded as a linked list - */ -struct afm_db { - int refcount; /* count of references to the structure */ - struct afm_db_dir *dirhead; /* first directory of the set */ - struct afm_db_dir *dirtail; /* last directory of the set */ - struct afm_apps applications; /* the data about applications */ -}; - -/* - * The structure enumdata records data used when enumerating - * application directories of a root directory. - */ -struct enumdata { - char path[PATH_MAX]; /* "current" computed path */ - int length; /* length of path */ - struct afm_apps apps; /* */ -}; - -/* - * Release the data of the afm_apps object 'apps'. - */ -static void apps_put(struct afm_apps *apps) -{ - json_object_put(apps->pubarr); - json_object_put(apps->direct); - json_object_put(apps->byapp); -} - -/* - * Adds the application widget 'desc' of the directory 'path' to the - * afm_apps object 'apps'. - * Returns 0 in case of success. - * Returns -1 and set errno in case of error - */ -static int addwgt(struct afm_apps *apps, const char *path, - const struct wgt_desc *desc) -{ - const struct wgt_desc_feature *feat; - struct json_object *priv, *pub, *bya, *plugs, *str; - - /* create the application structure */ - priv = json_object_new_object(); - if (!priv) - return -1; - - pub = j_add_new_object(priv, "public"); - if (!pub) - goto error; - - plugs = j_add_new_array(priv, "bindings"); - if (!plugs) - goto error; - - if(!j_add_string(priv, "id", desc->id) - || !j_add_string(priv, "path", path) - || !j_add_string(priv, "content", desc->content_src) - || !j_add_string(priv, "type", desc->content_type) - || !j_add_string(pub, "id", desc->idaver) - || !j_add_string(pub, "version", desc->version) - || !j_add_integer(pub, "width", desc->width) - || !j_add_integer(pub, "height", desc->height) - || !j_add_string(pub, "name", desc->name) - || !j_add_string(pub, "description", desc->description) - || !j_add_string(pub, "shortname", desc->name_short) - || !j_add_string(pub, "author", desc->author)) - goto error; - - /* extract bindings from features */ - feat = desc->features; - while (feat) { - static const char prefix[] = FWK_PREFIX_BINDING; - if (!memcmp(feat->name, prefix, sizeof prefix - 1)) { - str = json_object_new_string ( - feat->name + sizeof prefix - 1); - if (str == NULL) - goto error; - if (json_object_array_add(plugs, str)) { - json_object_put(str); - goto error; - } - } - feat = feat->next; - } - - /* record the application structure */ - if (!j_add(apps->direct, desc->idaver, priv)) - goto error; - - if (json_object_array_add(apps->pubarr, pub)) - goto error; - json_object_get(pub); - - if (!json_object_object_get_ex(apps->byapp, desc->id, &bya)) { - bya = j_add_new_object(apps->byapp, desc->id); - if (!bya) - goto error; - } - - if (!j_add(bya, desc->version, priv)) - goto error; - json_object_get(priv); - return 0; - -error: - json_object_put(priv); - return -1; -} - -/* - * Adds the application widget in the directory 'path' to the - * afm_apps object 'apps'. - * Returns 0 in case of success. - * Returns -1 and set errno in case of error - */ -static int addapp(struct afm_apps *apps, const char *path) -{ - int rc; - struct wgt_info *info; - - /* connect to the widget */ - info = wgt_info_createat(AT_FDCWD, path, 0, 1, 0); - if (info == NULL) { - if (errno == ENOENT) - return 0; /* silently ignore bad directories */ - return -1; - } - /* adds the widget */ - rc = addwgt(apps, path, wgt_info_desc(info)); - wgt_info_unref(info); - return rc; -} - -/* - * Enumerate the directories designated by 'data' and call the - * function 'callto' for each of them. - */ -static int enumentries(struct enumdata *data, int (*callto)(struct enumdata *)) -{ - DIR *dir; - int rc; - char *beg; - struct dirent *e; - size_t len; - - /* opens the directory */ - dir = opendir(data->path); - if (!dir) - return -1; - - /* prepare appending entry names */ - beg = data->path + data->length; - *beg++ = '/'; - - /* enumerate entries */ - for(;;) { - errno = 0; - e = readdir(dir); - if (!e) { - rc = !errno - 1; - break; - } - if (e->d_name[0] != '.' || (e->d_name[1] - && (e->d_name[1] != '.' || e->d_name[2]))) { - /* prepare callto */ - len = strlen(e->d_name); - if (beg + len >= data->path + sizeof data->path) { - errno = ENAMETOOLONG; - return -1; - } - data->length = (int)(stpcpy(beg, e->d_name) - - data->path); - /* call the function */ - rc = callto(data); - if (rc) - break; - } - } - closedir(dir); - return rc; -} - -/* - * called for each version directory. - */ -static int recordapp(struct enumdata *data) -{ - return addapp(&data->apps, data->path); -} - -/* - * called for each application directory. - * enumerate directories of the existing versions. - */ -static int enumvers(struct enumdata *data) -{ - int rc = enumentries(data, recordapp); - return !rc || errno != ENOTDIR ? 0 : rc; -} - -/* - * Adds the directory of 'path' and 'type' to the afm_db object 'afdb'. - * Returns 0 in case of success. - * Returns -1 and set errno in case of error - * Possible errno values: ENOMEM, ENAMETOOLONG - */ -static int add_dir(struct afm_db *afdb, const char *path, enum dir_type type) -{ - struct afm_db_dir *dir; - size_t len; - - assert(afdb); - - /* check size */ - len = strlen(path); - if (len >= PATH_MAX) { - errno = ENAMETOOLONG; - return -1; - } - - /* avoiding duplications */ - dir = afdb->dirhead; - while(dir != NULL && (strcmp(dir->path, path) || dir->type != type)) - dir = dir ->next; - if (dir != NULL) - return 0; - - /* allocates the structure */ - dir = malloc(strlen(path) + sizeof * dir); - if (dir == NULL) { - errno = ENOMEM; - return -1; - } - - /* add it at tail */ - dir->next = NULL; - dir->type = type; - strcpy(dir->path, path); - if (afdb->dirtail == NULL) - afdb->dirhead = dir; - else - afdb->dirtail->next = dir; - afdb->dirtail = dir; - return 0; -} - -/* - * Creates an afm_db object and returns it with one reference added. - * Return NULL with errno = ENOMEM if memory exhausted. - */ -struct afm_db *afm_db_create() -{ - struct afm_db *afdb = malloc(sizeof * afdb); - if (afdb == NULL) - errno = ENOMEM; - else { - afdb->refcount = 1; - afdb->dirhead = NULL; - afdb->dirtail = NULL; - afdb->applications.pubarr = NULL; - afdb->applications.direct = NULL; - afdb->applications.byapp = NULL; - } - return afdb; -} - -/* - * Adds a reference to an existing afm_db. - */ -void afm_db_addref(struct afm_db *afdb) -{ - assert(afdb); - afdb->refcount++; -} - -/* - * Removes a reference to an existing afm_db object. - * Removes the objet if there no more reference to it. - */ -void afm_db_unref(struct afm_db *afdb) -{ - struct afm_db_dir *dir; - - assert(afdb); - if (!--afdb->refcount) { - /* no more reference, clean the memory used by the object */ - apps_put(&afdb->applications); - while (afdb->dirhead != NULL) { - dir = afdb->dirhead; - afdb->dirhead = dir->next; - free(dir); - } - free(afdb); - } -} - -/* - * Adds the root directory of 'path' to the afm_db object 'afdb'. - * Be aware that no check is done on the directory of 'path' that will - * only be used within calls to the function 'afm_db_update_applications'. - * Returns 0 in case of success. - * Returns -1 and set errno in case of error - * Possible errno values: ENOMEM, ENAMETOOLONG - */ -int afm_db_add_root(struct afm_db *afdb, const char *path) -{ - return add_dir(afdb, path, type_root); -} - -/* - * Adds the application directory of 'path' to the afm_db object 'afdb'. - * Be aware that no check is done on the directory of 'path' that will - * only be used within calls to the function 'afm_db_update_applications'. - * Returns 0 in case of success. - * Returns -1 and set errno in case of error - * Possible errno values: ENOMEM, ENAMETOOLONG - */ -int afm_db_add_application(struct afm_db *afdb, const char *path) -{ - return add_dir(afdb, path, type_app); -} - -/* - * Regenerate the list of applications of the afm_bd object 'afdb'. - * Returns 0 in case of success. - * Returns -1 and set errno in case of error - */ -int afm_db_update_applications(struct afm_db *afdb) -{ - int rc; - struct enumdata edata; - struct afm_apps oldapps; - struct afm_db_dir *dir; - - /* create the result */ - edata.apps.pubarr = json_object_new_array(); - edata.apps.direct = json_object_new_object(); - edata.apps.byapp = json_object_new_object(); - if (edata.apps.pubarr == NULL || edata.apps.direct == NULL - || edata.apps.byapp == NULL) { - errno = ENOMEM; - goto error; - } - /* for each directory of afdb */ - for (dir = afdb->dirhead ; dir != NULL ; dir = dir->next) { - if (dir->type == type_root) { - edata.length = (int)(stpcpy(edata.path, dir->path) - - edata.path); - assert(edata.length < (int)sizeof edata.path); - /* enumerate the applications */ - rc = enumentries(&edata, enumvers); - if (rc) - goto error; - } else { - rc = addapp(&edata.apps, dir->path); - } - } - /* commit the result */ - oldapps = afdb->applications; - afdb->applications = edata.apps; - apps_put(&oldapps); - return 0; - -error: - apps_put(&edata.apps); - return -1; -} - -/* - * Ensure that applications of the afm_bd object 'afdb' are listed. - * Returns 0 in case of success. - * Returns -1 and set errno in case of error - */ -int afm_db_ensure_applications(struct afm_db *afdb) -{ - return afdb->applications.pubarr ? 0 : afm_db_update_applications(afdb); -} - -/* - * Get the list of the applications public data of the afm_db object 'afdb'. - * The list is returned as a JSON-array that must be released using - * 'json_object_put'. - * Returns NULL in case of error. - */ -struct json_object *afm_db_application_list(struct afm_db *afdb) -{ - return afm_db_ensure_applications(afdb) ? NULL - : json_object_get(afdb->applications.pubarr); -} - -/* - * Get the private data of the applications of 'id' in the afm_db object 'afdb'. - * It returns a JSON-object that must be released using 'json_object_put'. - * Returns NULL in case of error. - */ -struct json_object *afm_db_get_application(struct afm_db *afdb, const char *id) -{ - int i; - struct json_object *result; - - if (afm_db_ensure_applications(afdb)) - return NULL; - - /* search case sensitively */ - if (json_object_object_get_ex( afdb->applications.direct, id, &result)) - return json_object_get(result); - - /* fallback to a case insensitive search */ - i = json_object_array_length(afdb->applications.pubarr); - while (i) { - result = json_object_array_get_idx(afdb->applications.pubarr, --i); - if (result - && json_object_object_get_ex(result, "id", &result) - && !strcasecmp(id, json_object_get_string(result))) { - if (json_object_object_get_ex( afdb->applications.direct, - json_object_get_string(result), - &result)) - return json_object_get(result); - else - return NULL; - } - } - return NULL; -} - -/* - * Get the public data of the applications of 'id' in the afm_db object 'afdb'. - * It returns a JSON-object that must be released using 'json_object_put'. - * Returns NULL in case of error. - */ -struct json_object *afm_db_get_application_public(struct afm_db *afdb, - const char *id) -{ - struct json_object *result; - struct json_object *priv = afm_db_get_application(afdb, id); - if (priv == NULL) - return NULL; - if (json_object_object_get_ex(priv, "public", &result)) - json_object_get(result); - else - result = NULL; - json_object_put(priv); - return result; -} - - - - -#if defined(TESTAPPFWK) -#include <stdio.h> -int main() -{ -struct afm_db *afdb = afm_db_create(); -afm_db_add_root(afdb,FWK_APP_DIR); -afm_db_update_applications(afdb); -printf("array = %s\n", json_object_to_json_string_ext(afdb->applications.pubarr, 3)); -printf("direct = %s\n", json_object_to_json_string_ext(afdb->applications.direct, 3)); -printf("byapp = %s\n", json_object_to_json_string_ext(afdb->applications.byapp, 3)); -return 0; -} -#endif - diff --git a/src/afm-db.h b/src/afm-db.h deleted file mode 100644 index 34ee2bb..0000000 --- a/src/afm-db.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright 2015, 2016, 2017 IoT.bzh - - author: José Bollo <jose.bollo@iot.bzh> - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -struct afm_db; - -extern struct afm_db *afm_db_create(); -extern void afm_db_addref(struct afm_db *afdb); -extern void afm_db_unref(struct afm_db *afdb); - -extern int afm_db_add_root(struct afm_db *afdb, const char *path); -extern int afm_db_add_application(struct afm_db *afdb, const char *path); - -extern int afm_db_update_applications(struct afm_db *afdb); -extern int afm_db_ensure_applications(struct afm_db *afdb); - -extern struct json_object *afm_db_application_list(struct afm_db *afdb); -extern struct json_object *afm_db_get_application(struct afm_db *afdb, const char *id); -extern struct json_object *afm_db_get_application_public(struct afm_db *afdb, const char *id); - diff --git a/src/afm-launch-mode.c b/src/afm-launch-mode.c deleted file mode 100644 index fa4cd70..0000000 --- a/src/afm-launch-mode.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - Copyright 2015, 2016, 2017 IoT.bzh - - author: José Bollo <jose.bollo@iot.bzh> - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -#include <string.h> -#include <assert.h> - -#include "afm-launch-mode.h" - -/* - * There is actually 2 possible launch mode: - * - local - * - remote - */ -static const char s_mode_local[] = "local"; -static const char s_mode_remote[] = "remote"; - -/* - * Records the current default mode - */ -static enum afm_launch_mode default_mode = mode_local; - -/* - * Set the default launch mode to 'mode' - */ -int is_valid_launch_mode(enum afm_launch_mode mode) -{ - switch(mode) { - case mode_local: - case mode_remote: - return 1; - default: - return 0; - } -} - -/* - * Get the default launch mode - * - * Ensure a valid result - */ -enum afm_launch_mode get_default_launch_mode() -{ - return default_mode; -} - -/* - * Set the default launch mode to 'mode' - * - * Requires 'mode' to be valid - */ -void set_default_launch_mode(enum afm_launch_mode mode) -{ - assert(is_valid_launch_mode(mode)); - default_mode = mode; -} - -/* - * Get the launch mode corresponding to the 'name' - * - * Returns invalid_launch_mode if the 'name' is not valid. - */ -enum afm_launch_mode launch_mode_of_name(const char *name) -{ - if (name) { - if (!strcmp(name, s_mode_local)) - return mode_local; - if (!strcmp(name, s_mode_remote)) - return mode_remote; - } - return invalid_launch_mode; -} - -/* - * Get the name of the launch 'mode' - * - * Requires 'mode' to be valid - */ -const char *name_of_launch_mode(enum afm_launch_mode mode) -{ - assert(is_valid_launch_mode(mode)); - switch (mode) { - case mode_local: return s_mode_local; - case mode_remote: return s_mode_remote; - default: return NULL; - } -} diff --git a/src/afm-launch-mode.h b/src/afm-launch-mode.h deleted file mode 100644 index d032b6c..0000000 --- a/src/afm-launch-mode.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright 2015, 2016, 2017 IoT.bzh - - author: José Bollo <jose.bollo@iot.bzh> - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -enum afm_launch_mode { - invalid_launch_mode = 0, - mode_local = 1, - mode_remote = 2 -}; - -extern int is_valid_launch_mode(enum afm_launch_mode mode); - -extern enum afm_launch_mode get_default_launch_mode(); -extern void set_default_launch_mode(enum afm_launch_mode mode); - -extern enum afm_launch_mode launch_mode_of_name(const char *name); -extern const char *name_of_launch_mode(enum afm_launch_mode mode); - diff --git a/src/afm-launch.c b/src/afm-launch.c deleted file mode 100644 index 1a354a1..0000000 --- a/src/afm-launch.c +++ /dev/null @@ -1,959 +0,0 @@ -/* - Copyright 2015, 2016, 2017 IoT.bzh - - author: José Bollo <jose.bollo@iot.bzh> - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -#define _GNU_SOURCE - -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <limits.h> -#include <errno.h> -#include <string.h> -#include <fcntl.h> -#include <assert.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <poll.h> -#include <signal.h> - -extern char **environ; - -#include "verbose.h" -#include "afm-launch-mode.h" -#include "afm-launch.h" -#include "secmgr-wrap.h" - -#define DEFAULT_TYPE "text/html" - -/* - * structure for a launching type - */ -struct type_list { - struct type_list *next; /* next type */ - char type[1]; /* type name */ -}; - -/* - * structure for launch vectors - */ -struct exec_vector { - int has_readyfd; /* has a request for readyness */ - const char **args; /* vector of arguments */ -}; - -struct desc_launcher { - struct desc_launcher *next; /* next launcher description */ - enum afm_launch_mode mode; /* the launch mode */ - struct type_list *types; /* the launched types */ - struct exec_vector execs[2]; /* the launching vectors */ -}; - -struct launchparam { - int port; - int readyfd; - char **uri; - const char *secret; - const char *datadir; - struct exec_vector *execs; -}; - -/* - * Structure for reading the configuration file - */ -struct confread { - const char *filepath; /* path of the configuration file */ - FILE *file; /* handle to the file */ - int lineno; /* current line number */ - int index; /* start of the current token (in buffer) */ - int length; /* length of the current token */ - char buffer[4096]; /* current line */ -}; - -/* - * list of launch descriptions - */ -struct desc_launcher *launchers = NULL; - -/* - * the group when launched (to avoid the setgid effect) - */ -static gid_t groupid = 0; - -/* - * separators within configuration files - */ -static const char separators[] = " \t\n"; - -/* - * default string emitted when for application not having signal - */ -static const char readystr[] = "READY=1"; - -/* - * default time out for readiness of signaling applications - */ -static const int ready_timeout = 1500; - -#if defined(DUMP_LAUNCHERS) -/* - * dump all the known launchers to the 'file' - */ -static void dump_launchers(FILE *file) -{ - int j, k; - struct desc_launcher *desc; - struct type_list *type; - - for (desc = launchers ; desc != NULL ; desc = desc->next) { - fprintf(file, "mode %s\n", name_of_launch_mode(desc->mode)); - for (type = desc->types ; type != NULL ; type = type->next) - fprintf(file, "%s\n", type->type); - for ( j = 0 ; j < 2 ; j++) - if (desc->execs[j].args != NULL) { - for (k = 0; desc->execs[j].args[k] != NULL; k++) - fprintf(file, " %s", - desc->execs[j].args[k]); - fprintf(file, "\n"); - } - fprintf(file, "\n"); - } -} -#endif - -/* - * update 'cread' to point the the next token - * returns the length of the token that is nul if no - * more token exists in the line - */ -static int next_token(struct confread *cread) -{ - int idx = cread->index + cread->length; - cread->index = idx + (int)strspn(&cread->buffer[idx], separators); - cread->length = (int)strcspn(&cread->buffer[cread->index], separators); - return cread->length; -} - -/* - * reads the next line, skipping empty lines or lines - * having only comments. - * returns either 0 at end of the file, -1 in case of error or - * in case of success the length of the first token. - */ -static int read_line(struct confread *cread) -{ - while (fgets(cread->buffer, sizeof cread->buffer, cread->file) != NULL) { - cread->lineno++; - cread->index = (int)strspn(cread->buffer, separators); - if (cread->buffer[cread->index] - && cread->buffer[cread->index] != '#') { - cread->length = (int)strcspn( - &cread->buffer[cread->index], separators); - assert(cread->length > 0); - return cread->length; - } - } - if (ferror(cread->file)) { - ERROR("%s:%d: error while reading, %m", cread->filepath, - cread->lineno); - return -1; - } - return 0; -} - -/* - * extract from 'cread' a launch vector that is allocated in - * one piece of memory. - * 'cread' is left unchanged (index and length are not changed) - */ -static const char **read_vector(struct confread *cread) -{ - int index0, length0; - const char **vector; - char *args; - unsigned count, length; - - /* record origin */ - index0 = cread->index; - length0 = cread->length; - - /* count */ - count = 0; - length = 0; - while(cread->length) { - count++; - length += (unsigned)cread->length; - next_token(cread); - } - - /* allocates */ - cread->index = index0; - cread->length = length0; - vector = malloc(length + count + (count + 1) * sizeof(char*)); - if (vector == NULL) - return NULL; - - /* copies */ - args = (char*)(vector + count + 1); - count = 0; - while(cread->length) { - vector[count++] = args; - memcpy(args, &cread->buffer[cread->index], - (unsigned)cread->length); - args += cread->length; - *args++ = 0; - next_token(cread); - } - vector[count] = NULL; - cread->index = index0; - cread->length = length0; - return vector; -} - -/* - * Reads the type from 'cread' directly in the list item and return it. - * returns NULL in case or error. - * errno: - * - EINVAL extra characters - * - ENOMEM memory depletion - */ -static struct type_list *read_type(struct confread *cread) -{ - int index, length; - struct type_list *result; - - /* 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 type %.*s", - cread->filepath, cread->lineno, length, - &cread->buffer[index]); - errno = EINVAL; - return NULL; - } - - /* allocate structure */ - result = malloc(sizeof(struct type_list) + (unsigned)length); - if (result == NULL) { - ERROR("%s:%d: out of memory", cread->filepath, cread->lineno); - errno = ENOMEM; - return NULL; - } - - /* fill the structure */ - memcpy(result->type, &cread->buffer[index], (unsigned)length); - result->type[length] = 0; - return result; -} - -/* - * Reads the mode from 'cread' and return it. - * returns invalid_launch_mode in case or error. - * errno: - * - EINVAL no mode or extra characters or invalid mode - */ -static enum afm_launch_mode read_mode(struct confread *cread) -{ - int index, length; - enum afm_launch_mode result; - - 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_name(&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; -} - -/* - * free the memory used by 'types' - */ -static void free_type_list(struct type_list *types) -{ - while (types != NULL) { - struct type_list *next = types->next; - free(types); - types = next; - } -} - -/* - * reads the configuration file handled by 'cread' - * and adds its contents to the launcher list - * - * returns 0 in case of success or -1 in case of error. - */ -static int read_launchers(struct confread *cread) -{ - int rc, has_readyfd; - struct type_list *types, *lt; - struct desc_launcher *desc; - enum afm_launch_mode mode; - const char **vector; - - /* reads the file */ - lt = NULL; - types = NULL; - desc = NULL; - mode = invalid_launch_mode; - rc = read_line(cread); - while (rc > 0) { - if (cread->index == 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; - } - 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" - " (the maximum count is 2)", - cread->filepath, cread->lineno); - errno = EINVAL; - return -1; - } else { - has_readyfd = NULL != strstr( - &cread->buffer[cread->index], "%R"); - 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].has_readyfd = has_readyfd; - desc->execs[0].args = vector; - desc->execs[1].has_readyfd = 0; - desc->execs[1].args = NULL; - types = NULL; - launchers = desc; - } else { - desc->execs[1].has_readyfd = has_readyfd; - desc->execs[1].args = 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; -} - -/* - * reads the configuration file 'filepath' - * and adds its contents to the launcher list - * - * returns 0 in case of success or -1 in case of error. - */ -static int read_configuration_file(const char *filepath) -{ - int rc; - struct confread cread; - - /* opens the configuration file */ - cread.file = fopen(filepath, "r"); - if (cread.file == NULL) { - /* error */ - ERROR("can't read file %s: %m", filepath); - rc = -1; - } else { - /* reads it */ - cread.filepath = filepath; - cread.lineno = 0; - rc = read_launchers(&cread); - fclose(cread.file); - } - return rc; -} - -/* - * Creates a secret in 'buffer' - */ -static void mksecret(char buffer[9]) -{ - snprintf(buffer, 9, "%08lX", (0xffffffff & random())); -} - -/* - * Allocates a port and return it. - */ -static int mkport() -{ - static int port_ring = 12345; - int port = port_ring; - if (port < 12345 || port > 15432) - port = 12345; - port_ring = port + 1; - return port; -} - -/* -%% % -%a appid desc->appid -%b bindings desc->bindings -%c content desc->content -%D datadir params->datadir -%H height desc->height -%h homedir desc->home -%I icondir FWK_ICON_DIR -%m mime-type desc->type -%n name desc->name -%P port params->port -%r rootdir desc->path -%R readyfd params->readyfd -%S secret params->secret -%W width desc->width -*/ - -/* - * Union for handling either scalar arguments or vectorial arguments. - */ -union arguments { - char *scalar; /* string of space separated arguments */ - char **vector; /* vector of arguments */ -}; - -/* - * Computes the substitutions of 'args' according to the - * data of 'desc' and 'params'. The result is a single - * piece of memory (that must be freed in one time) - * containing either a vector or a string depending on - * the value of 'wants_vector'. - * - * The vectors are made of an array pointers terminated by - * the NULL pointer. - * - * Returns the resulting value or NULL in case of error - */ -static union arguments instantiate_arguments( - const char * const *args, - struct afm_launch_desc *desc, - struct launchparam *params, - int wants_vector -) -{ - const char * const *iter; - const char *p, *v; - char *data, c, sep; - unsigned n, s; - union arguments result; - char port[20], width[20], height[20], readyfd[20], mini[3]; - - /* init */ - sep = wants_vector ? 0 : ' '; - mini[0] = '%'; - mini[2] = 0; - - /* - * loop that either compute the size and build the result - * advantage: appears only in one place - */ - result.vector = NULL; /* initialise both to avoid */ - result.scalar = NULL; /* a very stupid compiler warning */ - data = NULL; /* no data for the first iteration */ - n = s = 0; - for (;;) { - /* iterate over arguments */ - for (n = 0, iter = args ; (p = *iter) != NULL ; iter++) { - /* init the vector */ - if (data && !sep) - result.vector[n] = data; - n++; - - /* scan the argument */ - while((c = *p++) != 0) { - if (c != '%') { - /* standard character */ - if (data) - *data++ = c; - else - s++; - } else { - /* substitutions */ - /* (convert num->string only once) */ - c = *p++; - switch (c) { - case 'a': v = desc->appid; break; - case 'b': - v = "" /*TODO:desc->bindings*/; - break; - case 'c': v = desc->content; break; - case 'D': v = params->datadir; break; - case 'H': - if(!data) - sprintf(height, "%d", - desc->height); - v = height; - break; - case 'h': v = desc->home; break; - case 'I': v = FWK_ICON_DIR; break; - case 'm': v = desc->type; break; - case 'n': v = desc->name; break; - case 'P': - if(!data) - sprintf(port, "%d", - params->port); - v = port; - break; - case 'R': - if(!data) - sprintf(readyfd, "%d", - params->readyfd); - v = readyfd; - break; - case 'r': v = desc->path; break; - case 'S': v = params->secret; break; - case 'W': - if(!data) - sprintf(width, "%d", - desc->width); - v = width; - break; - case '%': - c = 0; - /*@fallthrough@*/ - default: - mini[1] = c; - v = mini; - break; - } - if (data) - data = stpcpy(data, v); - else - s += (unsigned)strlen(v); - } - } - /* terminate the argument */ - if (data) - *data++ = sep; - else - s++; - } - if (!data) { - /* first iteration: allocation */ - if (sep) { - result.scalar = malloc(s); - data = result.scalar; - } else { - result.vector = malloc((n+1)*sizeof(char*) + s); - if (result.vector != NULL) - data = (char*)(&result.vector[n + 1]); - } - if (!data) { - errno = ENOMEM; - return result; - } - } else { - /* second iteration: termination */ - if (sep) - *--data = 0; - else - result.vector[n] = NULL; - return result; - } - } -} - -/* - * Launchs (fork-execs) the program described by 'exec' - * using the parameters of 'desc' and 'params' to instantiate - * it. The created process is attached to the process group 'progrp'. - * - * After being created and before to be launched, the process - * is put in its security environment and its directory is - * changed to params->datadir. - * - * Returns the pid of the created process or -1 in case of error. - */ -static pid_t launch( - struct afm_launch_desc *desc, - struct launchparam *params, - struct exec_vector *exec, - pid_t progrp -) -{ - int rc; - char **args, **env; - pid_t pid; - int rpipe[2]; - struct pollfd pfd; - - /* prepare the pipes */ - rc = pipe(rpipe); - if (rc < 0) { - ERROR("error while calling pipe2: %m"); - return -1; - } - - /* instanciate the arguments */ - params->readyfd = rpipe[1]; - args = instantiate_arguments(exec->args, desc, params, 1).vector; - env = instantiate_arguments((const char * const*)environ, - desc, params, 1).vector; - if (args == NULL || env == NULL) { - close(rpipe[0]); - close(rpipe[1]); - free(args); - free(env); - ERROR("out of memory in master"); - errno = ENOMEM; - return -1; - } - - /* fork the master child */ - pid = fork(); - if (pid < 0) { - - /********* can't fork ************/ - - close(rpipe[0]); - close(rpipe[1]); - free(args); - free(env); - ERROR("master fork failed: %m"); - return -1; - } - if (pid) { - - /********* in the parent process ************/ - - close(rpipe[1]); - free(args); - free(env); - pfd.fd = rpipe[0]; - pfd.events = POLLIN; - - /* wait for readyness */ - poll(&pfd, 1, ready_timeout); - close(rpipe[0]); - return pid; - } - - /********* in the child process ************/ - - close(rpipe[0]); - - /* set name by appid */ - verbose_set_name(desc->appid, 0); - - /* avoid set-gid effect */ - setresgid(groupid, groupid, groupid); - - /* enter the process group */ - rc = setpgid(0, progrp); - if (rc) { - ERROR("setpgid failed"); - _exit(1); - } - - /* enter security mode */ - rc = secmgr_prepare_exec(desc->appid); - if (rc < 0) { - ERROR("call to secmgr_prepare_exec failed: %m"); - _exit(1); - } - - /* enter the datadirectory */ - rc = mkdir(params->datadir, 0755); - if (rc && errno != EEXIST) { - ERROR("creation of datadir %s failed: %m", params->datadir); - _exit(1); - } - rc = chdir(params->datadir); - if (rc) { - ERROR("can't enter the datadir %s: %m", params->datadir); - _exit(1); - } - - /* signal if needed */ - if (!exec->has_readyfd) { - write(rpipe[1], readystr, sizeof(readystr) - 1); - close(rpipe[1]); - } - - /* executes the process */ - rc = execve(args[0], args, env); - access(args[0], X_OK); - ERROR("failed to exec master %s: %m", args[0]); - _exit(1); - return -1; -} - -/* - * Launches the application 'desc' in local mode using - * 'params' and store the resulting pids in 'children'. - * - * Returns 0 in case of success or -1 in case of error. - */ -static int launch_local( - struct afm_launch_desc *desc, - pid_t children[2], - struct launchparam *params -) -{ - /* launches the first, making it group leader */ - children[0] = launch(desc, params, ¶ms->execs[0], 0); - if (children[0] <= 0) - return -1; - - /* nothing more to launch ? */ - if (params->execs[1].args == NULL) - return 0; - - /* launches the second in the group of the first */ - children[1] = launch(desc, params, ¶ms->execs[1], children[0]); - if (children[1] > 0) - return 0; - - /* kill all on error */ - killpg(children[0], SIGKILL); - return -1; -} - -/* - * Launches the application 'desc' in remote mode using - * 'params' and store the resulting pids in 'children'. - * - * Returns 0 in case of success or -1 in case of error. - */ -static int launch_remote( - struct afm_launch_desc *desc, - pid_t children[2], - struct launchparam *params -) -{ - char *uri; - - /* instanciate the uri */ - if (params->execs[1].args == NULL) - uri = NULL; - else - uri = instantiate_arguments(params->execs[1].args, desc, - params, 0).scalar; - if (uri == NULL) { - ERROR("out of memory for remote uri"); - errno = ENOMEM; - return -1; - } - - /* launch the command */ - children[0] = launch(desc, params, ¶ms->execs[0], 0); - if (children[0] <= 0) { - free(uri); - return -1; - } - - /* returns the uri in params */ - *params->uri = uri; - return 0; -} - -/* - * Searchs the launcher descritpion for the given 'type' and 'mode' - * - * Returns the description found or NULL if nothing matches. - */ -static struct desc_launcher *search_launcher(const char *type, - enum afm_launch_mode mode) -{ - struct desc_launcher *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 (!strcasecmp(tl->type, type)) - return dl; - return NULL; -} - -/* - * Launches the application described by 'desc' - * and, in case of success, returns the resulting data - * in 'children' and 'uri'. - * - * Returns 0 in case of success or -1 in case of error. - */ -int afm_launch(struct afm_launch_desc *desc, pid_t children[2], char **uri) -{ - int rc; - char datadir[PATH_MAX]; - char secret[9]; - struct launchparam params; - const char *type; - struct desc_launcher *dl; - - /* should be init */ - assert(groupid != 0); - assert(is_valid_launch_mode(desc->mode)); - assert(desc->mode == mode_local || uri != NULL); - assert(uri == NULL || *uri == NULL); - - /* init */ - children[0] = 0; - children[1] = 0; - - /* what launcher ? */ - type = desc->type != NULL && *desc->type ? desc->type : DEFAULT_TYPE; - dl = search_launcher(type, desc->mode); - if (dl == NULL) { - ERROR("launcher not found for type %s and mode %s!", - type, name_of_launch_mode(desc->mode)); - errno = ENOENT; - return -1; - } - - /* prepare paths */ - rc = snprintf(datadir, sizeof datadir, "%s/%s", - desc->home, desc->appid); - if (rc < 0 || rc >= (int)sizeof datadir) { - ERROR("overflow for datadir"); - errno = EINVAL; - return -1; - } - - /* make the secret and port */ - mksecret(secret); - params.uri = uri; - params.port = mkport(); - params.secret = secret; - params.datadir = datadir; - params.execs = dl->execs; - - switch (desc->mode) { - case mode_local: - return launch_local(desc, children, ¶ms); - case mode_remote: - return launch_remote(desc, children, ¶ms); - default: - assert(0); - return -1; - } -} - -/* - * Initialise the module - * - * Returns 0 on success or else -1 in case of failure - */ -int afm_launch_initialize() -{ - int rc; - gid_t r, e, s; - - /* compute the groupid to set at launch */ - getresgid(&r, &e, &s); - if (s && s != e) - groupid = s; /* the original groupid is used */ - else - groupid = (gid_t)-1; - - /* reads the configuration file */ - rc = read_configuration_file(FWK_LAUNCH_CONF); -#if defined(DUMP_LAUNCHERS) - if (!rc) - dump_launchers(stderr); -#endif - - return rc; -} - diff --git a/src/afm-launch.h b/src/afm-launch.h deleted file mode 100644 index 916079b..0000000 --- a/src/afm-launch.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright 2015, 2016, 2017 IoT.bzh - - author: José Bollo <jose.bollo@iot.bzh> - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/* - * Structure describing what is to be launched - */ -struct afm_launch_desc { - const char *path; /* to the widget directory */ - const char *appid; /* application identifier */ - const char *content; /* content to launch */ - const char *type; /* type to launch */ - const char *name; /* name of the application */ - const char *home; /* home directory of the applications */ - const char **bindings; /* bindings for the application */ - int width; /* requested width */ - int height; /* requested height */ - enum afm_launch_mode mode; /* launch mode */ -}; - -int afm_launch_initialize(); - -int afm_launch(struct afm_launch_desc *desc, pid_t children[2], char **uri); - diff --git a/src/afm-run.c b/src/afm-run.c deleted file mode 100644 index 089aa77..0000000 --- a/src/afm-run.c +++ /dev/null @@ -1,781 +0,0 @@ -/* - Copyright 2015, 2016, 2017 IoT.bzh - - author: José Bollo <jose.bollo@iot.bzh> - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -#define _GNU_SOURCE - -#include <fcntl.h> -#include <unistd.h> -#include <signal.h> -#include <pwd.h> -#include <sys/types.h> -#include <errno.h> -#include <assert.h> -#include <stdio.h> -#include <limits.h> -#include <string.h> - -#include <linux/xattr.h> -#if SIMULATE_LIBSMACK -#include "simulation/smack.h" -#else -#include <sys/smack.h> -#endif - -#include <json-c/json.h> - -#include "verbose.h" -#include "utils-dir.h" -#include "utils-json.h" -#include "afm-launch-mode.h" -#include "afm-launch.h" -#include "afm-run.h" - -/* - * State of a launched/running application - */ -enum appstate { - as_starting, /* start in progress */ - as_running, /* started and running */ - as_paused, /* paused */ - as_terminating, /* termination in progress */ - as_terminated /* terminated */ -}; - -/* - * Structure for recording a runner - */ -struct apprun { - struct apprun *next_by_runid; /* link for hashing by runid */ - struct apprun *next_by_pgid; /* link for hashing by pgid */ - int runid; /* runid */ - pid_t pids[2]; /* pids (0: group leader, 1: slave) */ - enum appstate state; /* current state of the application */ - json_object *appli; /* json object describing the application */ -}; - -/* - * Count of item by hash table - */ -#define ROOT_RUNNERS_COUNT 32 - -/* - * Maximum count of simultaneous running application - */ -#define MAX_RUNNER_COUNT 32767 - -/* - * Hash tables of runners by runid and by pgid - */ -static struct apprun *runners_by_runid[ROOT_RUNNERS_COUNT]; -static struct apprun *runners_by_pgid[ROOT_RUNNERS_COUNT]; - -/* - * List of terminated runners - */ -static struct apprun *terminated_runners = NULL; - -/* - * Count of runners - */ -static int runnercount = 0; - -/* - * Last given runid - */ -static int runnerid = 0; - -/* - * Path name of the directory for applications in the - * home directory of the user. - */ -static const char fwk_user_app_dir[] = FWK_USER_APP_DIR; -static const char fwk_user_app_label[] = FWK_USER_APP_DIR_LABEL; - -/* - * Path of the root directory for applications of the - * current user - */ -static char *homeappdir; - -/****************** manages pids **********************/ - -/* - * Get a runner by its 'pid' (NULL if not found) - */ -static struct apprun *runner_of_pid(pid_t pid) -{ - int i; - struct apprun *result; - - for (i = 0 ; i < ROOT_RUNNERS_COUNT ; i++) { - result = runners_by_pgid[i]; - while (result != NULL) { - if (result->pids[0] == pid || result->pids[1] == pid) - return result; - result = result->next_by_pgid; - } - } - return NULL; -} - -/****************** manages pgids **********************/ - -/* - * Get a runner by its 'pgid' (NULL if not found) - */ -static struct apprun *runner_of_pgid(pid_t pgid) -{ - struct apprun *result; - - result = runners_by_pgid[pgid & (ROOT_RUNNERS_COUNT - 1)]; - while (result && result->pids[0] != pgid) - result = result->next_by_pgid; - return result; -} - -/* - * Insert a 'runner' for its pgid - */ -static void pgid_insert(struct apprun *runner) -{ - struct apprun **prev; - - prev = &runners_by_pgid[runner->pids[0] & (ROOT_RUNNERS_COUNT - 1)]; - runner->next_by_pgid = *prev; - *prev = runner; -} - -/* - * Remove a 'runner' for its pgid - */ -static void pgid_remove(struct apprun *runner) -{ - struct apprun **prev; - - prev = &runners_by_pgid[runner->pids[0] & (ROOT_RUNNERS_COUNT - 1)]; - while (*prev) { - if (*prev == runner) { - *prev = runner->next_by_pgid; - break; - } - prev = &(*prev)->next_by_pgid; - } -} - -/****************** manages runners (by runid) **********************/ - -/* - * Is a 'runner' alive? - */ -static inline int is_alive(struct apprun *runner) -{ - switch(runner->state) { - case as_terminating: - case as_terminated: - return 0; - default: - return 1; - } -} - -/* - * Is a 'runner' dead? - */ -static inline int is_dead(struct apprun *runner) -{ - switch(runner->state) { - case as_terminating: - case as_terminated: - return 1; - default: - return 0; - } -} - -/* - * Is a 'runner' running? - */ -static inline int is_running(struct apprun *runner) -{ - switch(runner->state) { - case as_starting: - case as_running: - return 1; - default: - return 0; - } -} - -/* - * Is a 'runner' paused? - */ -static inline int is_paused(struct apprun *runner) -{ - switch(runner->state) { - case as_paused: - return 1; - default: - return 0; - } -} - -/* - * Get a runner by its 'runid' (NULL if not found) - */ -static struct apprun *getrunner(int runid) -{ - struct apprun *result; - - result = runners_by_runid[runid & (ROOT_RUNNERS_COUNT - 1)]; - while (result && result->runid != runid) - result = result->next_by_runid; - return result; -} - -/* - * Get first runner of 'appli' (NULL if not found) - */ -static struct apprun *getrunner_appli(json_object *appli) -{ - int i; - struct apprun *result; - - for (i = 0 ; i < ROOT_RUNNERS_COUNT ; i++) { - result = runners_by_pgid[i]; - while (result != NULL) { - if (result->appli == appli) - return result; - result = result->next_by_pgid; - } - } - return NULL; -} - -/* - * Free an existing 'runner' - */ -static void freerunner(struct apprun *runner) -{ - struct apprun **prev; - - /* get previous pointer to runner */ - prev = &runners_by_runid[runner->runid & (ROOT_RUNNERS_COUNT - 1)]; - assert(*prev); - while(*prev != runner) { - prev = &(*prev)->next_by_runid; - assert(*prev); - } - - /* unlink */ - *prev = runner->next_by_runid; - runnercount--; - - /* release/free */ - json_object_put(runner->appli); - free(runner); -} - -/* - * Cleans the list of runners from its terminated - */ -static void cleanrunners() -{ - struct apprun *runner; - while (terminated_runners) { - runner = terminated_runners; - terminated_runners = runner->next_by_pgid; - freerunner(runner); - } -} - -/* - * Create a new runner for the 'appli' - * - * Returns the created runner or NULL - * in case of error. - */ -static struct apprun *createrunner(json_object *appli) -{ - struct apprun *result; - struct apprun **prev; - - /* cleanup */ - cleanrunners(); - - /* get a runid */ - if (runnercount >= MAX_RUNNER_COUNT) { - errno = EAGAIN; - return NULL; - } - do { - runnerid++; - if (runnerid > MAX_RUNNER_COUNT) - runnerid = 1; - } while(getrunner(runnerid)); - - /* create the structure */ - result = calloc(1, sizeof * result); - if (result == NULL) - errno = ENOMEM; - else { - /* initialize it linked to the list */ - prev = &runners_by_runid[runnerid & (ROOT_RUNNERS_COUNT - 1)]; - result->next_by_runid = *prev; - result->next_by_pgid = NULL; - result->runid = runnerid; - result->pids[0] = result->pids[1] = 0; - result->state = as_starting; - result->appli = json_object_get(appli); - *prev = result; - runnercount++; - } - return result; -} - -/**************** signaling ************************/ -#if 0 -static void started(int runid) -{ -} - -static void paused(int runid) -{ -} - -static void resumed(int runid) -{ -} - -static void terminated(int runid) -{ -} - -static void removed(int runid) -{ -} -#endif -/**************** running ************************/ - -/* - * Sends (with pgkill) the signal 'sig' to the process group - * for 'runid' and put the runner's state to 'tostate' - * in case of success. - * - * Only processes in the state 'as_running' or 'as_paused' - * can be signalled. - * - * Returns 0 in case of success or -1 in case of error. - */ -static int killrunner(int runid, int sig, enum appstate tostate) -{ - int rc; - struct apprun *runner = getrunner(runid); - if (runner == NULL) { - errno = ENOENT; - rc = -1; - } - else if (is_dead(runner)) { - errno = EINVAL; - rc = -1; - } - else if (runner->state == tostate) { - rc = 0; - } - else { - rc = killpg(runner->pids[0], sig); - if (!rc) - runner->state = tostate; - } - return rc; -} - -/* - * Signal callback called on SIGCHLD. This is set using sigaction. - */ -static void on_sigchld(int signum, siginfo_t *info, void *uctxt) -{ - struct apprun *runner; - - /* retrieves the runner */ - runner = runner_of_pid(info->si_pid); - if (!runner) - return; - - /* known runner, inspect cause of signal */ - switch(info->si_code) { - case CLD_EXITED: - case CLD_KILLED: - case CLD_DUMPED: - case CLD_TRAPPED: - /* update the state */ - runner->state = as_terminated; - /* remove it from pgid list */ - pgid_remove(runner); - runner->next_by_pgid = terminated_runners; - terminated_runners = runner; - /* ensures that all the group terminates */ - killpg(runner->pids[0], SIGKILL); - break; - - case CLD_STOPPED: - /* update the state */ - runner->state = as_paused; - break; - - case CLD_CONTINUED: - /* update the state */ - runner->state = as_running; - break; - } -} - -/**************** handle afm_launch_desc *********************/ - -/* - * Initialize the data of the launch description 'desc' - * for the application 'appli' and the 'mode'. - * - * Returns 0 in case of success or -1 in case of error. - */ -static int fill_launch_desc(struct json_object *appli, - enum afm_launch_mode mode, struct afm_launch_desc *desc) -{ - json_object *pub; - - assert(is_valid_launch_mode(mode)); - - /* main items */ - if(!j_read_object_at(appli, "public", &pub) - || !j_read_string_at(appli, "path", &desc->path) - || !j_read_string_at(appli, "id", &desc->appid) - || !j_read_string_at(appli, "content", &desc->content) - || !j_read_string_at(appli, "type", &desc->type) - || !j_read_string_at(pub, "name", &desc->name) - || !j_read_integer_at(pub, "width", &desc->width) - || !j_read_integer_at(pub, "height", &desc->height)) { - ERROR("bad internal description of the application to launch: %s", json_object_get_string(appli)); - errno = EINVAL; - return -1; - } - - /* bindings */ - { - /* TODO */ - static const char *null = NULL; - desc->bindings = &null; - } - - /* finaly */ - desc->home = homeappdir; - desc->mode = mode; - return 0; -} - -/**************** report state of runner *********************/ - -/* - * Creates a json object that describes the state of 'runner'. - * - * Returns the created object or NULL in case of error. - */ -static json_object *mkstate(struct apprun *runner) -{ - const char *state; - struct json_object *result, *obj, *pids; - int rc; - - /* the structure */ - result = json_object_new_object(); - if (result == NULL) - goto error; - - /* the runid */ - if (!j_add_integer(result, "runid", runner->runid)) - goto error2; - - /* the pids */ - if (is_alive(runner)) { - pids = j_add_new_array(result, "pids"); - if (!pids) - goto error2; - if (!j_add_integer(pids, NULL, runner->pids[0])) - goto error2; - if (runner->pids[1] && !j_add_integer(pids, NULL, runner->pids[1])) - goto error2; - } - - /* the state */ - switch(runner->state) { - case as_starting: - case as_running: - state = "running"; - break; - case as_paused: - state = "paused"; - break; - default: - state = "terminated"; - break; - } - if (!j_add_string(result, "state", state)) - goto error2; - - /* the application id */ - rc = json_object_object_get_ex(runner->appli, "public", &obj); - assert(rc); - rc = json_object_object_get_ex(obj, "id", &obj); - assert(rc); - if (!j_add(result, "id", obj)) - goto error2; - json_object_get(obj); - - /* done */ - return result; - -error2: - json_object_put(result); -error: - errno = ENOMEM; - return NULL; -} - -/**************** API handling ************************/ - -/* - * Starts the application described by 'appli' for the 'mode'. - * In case of remote start, it returns in uri the uri to - * connect to. - * - * A reference to 'appli' is kept during the live of the - * runner. This is made using json_object_get. Thus be aware - * that further modifications to 'appli' might create errors. - * - * Returns the runid in case of success or -1 in case of error - */ -int afm_run_start(struct json_object *appli, enum afm_launch_mode mode, - char **uri) -{ - struct apprun *runner; - struct afm_launch_desc desc; - int rc; - sigset_t saved, blocked; - - assert(is_valid_launch_mode(mode)); - assert(mode == mode_local || uri != NULL); - assert(uri == NULL || *uri == NULL); - - /* prepare to launch */ - rc = fill_launch_desc(appli, mode, &desc); - if (rc) - return rc; - runner = createrunner(appli); - if (!runner) - return -1; - - /* block children signals until launched */ - sigemptyset(&blocked); - sigaddset(&blocked, SIGCHLD); - sigprocmask(SIG_BLOCK, &blocked, &saved); - - /* launch now */ - rc = afm_launch(&desc, runner->pids, uri); - if (rc < 0) { - /* fork failed */ - sigprocmask(SIG_SETMASK, &saved, NULL); - ERROR("can't start, afm_launch failed: %m"); - freerunner(runner); - return -1; - } - - /* insert the pid */ - runner->state = as_running; - pgid_insert(runner); - rc = runner->runid; - - /* unblock children signal now */ - sigprocmask(SIG_SETMASK, &saved, NULL); - return rc; -} - -/* - * Returns the runid of a previously started application 'appli' - * or if none is running, starts the application described by 'appli' - * in local mode. - * - * A reference to 'appli' is kept during the live of the - * runner. This is made using json_object_get. Thus be aware - * that further modifications to 'appli' might create errors. - * - * Returns the runid in case of success or -1 in case of error - */ -int afm_run_once(struct json_object *appli) -{ - struct apprun *runner = getrunner_appli(appli); - return runner && is_alive(runner) ? runner->runid : afm_run_start(appli, mode_local, NULL); -} - -/* - * Terminates the runner of 'runid' - * - * Returns 0 in case of success or -1 in case of error - */ -int afm_run_terminate(int runid) -{ - return killrunner(runid, SIGTERM, as_terminating); -} - -/* - * Stops (aka pause) the runner of 'runid' - * - * Returns 0 in case of success or -1 in case of error - */ -int afm_run_pause(int runid) -{ - return killrunner(runid, SIGSTOP, as_paused); -} - -/* - * Continue (aka resume) the runner of 'runid' - * - * Returns 0 in case of success or -1 in case of error - */ -int afm_run_resume(int runid) -{ - return killrunner(runid, SIGCONT, as_running); -} - -/* - * Get the list of the runners. - * - * Returns the list or NULL in case of error. - */ -struct json_object *afm_run_list() -{ - struct json_object *result, *obj; - struct apprun *runner; - int i; - - /* creates the object */ - result = json_object_new_array(); - if (result == NULL) - goto error; - - /* iterate over runners */ - for (i = 0 ; i < ROOT_RUNNERS_COUNT ; i++) { - runner = runners_by_runid[i]; - while (runner) { - if (is_alive(runner)) { - /* adds the living runner */ - obj = mkstate(runner); - if (obj == NULL) - goto error2; - if (json_object_array_add(result, obj) == -1) { - json_object_put(obj); - goto error2; - } - } - runner = runner->next_by_runid; - } - } - return result; - -error2: - json_object_put(result); -error: - errno = ENOMEM; - return NULL; -} - -/* - * Get the state of the runner of 'runid'. - * - * Returns the state or NULL in case of success - */ -struct json_object *afm_run_state(int runid) -{ - struct apprun *runner = getrunner(runid); - if (runner == NULL || is_dead(runner)) { - errno = ENOENT; - return NULL; - } - return mkstate(runner); -} - -/**************** INITIALISATION **********************/ - -/* - * Initialize the module - */ -int afm_run_init() -{ - char buf[2048]; - int rc; - uid_t me; - struct passwd passwd, *pw; - struct sigaction siga; - - /* init launcher */ - rc = afm_launch_initialize(); - if (rc) - return rc; - - /* computes the 'homeappdir' */ - me = geteuid(); - rc = getpwuid_r(me, &passwd, buf, sizeof buf, &pw); - if (rc || pw == NULL) { - errno = rc ? errno : ENOENT; - ERROR("getpwuid_r failed for uid=%d: %m",(int)me); - return -1; - } - rc = asprintf(&homeappdir, "%s/%s", passwd.pw_dir, fwk_user_app_dir); - if (rc < 0) { - errno = ENOMEM; - ERROR("allocating homeappdir for uid=%d failed", (int)me); - return -1; - } - rc = create_directory(homeappdir, 0755, 1); - if (rc && errno != EEXIST) { - ERROR("creation of directory %s failed: %m", homeappdir); - free(homeappdir); - return -1; - } - rc = smack_remove_label_for_path(homeappdir, - XATTR_NAME_SMACKTRANSMUTE, 0); - if (rc < 0 && errno != ENODATA) { - ERROR("can't remove smack transmutation of directory %s: %m", - homeappdir); - free(homeappdir); - return -1; - } - rc = smack_set_label_for_path(homeappdir, XATTR_NAME_SMACK, 0, - fwk_user_app_label); - if (rc < 0) { - ERROR("can't set smack label %s to directory %s: %m", - fwk_user_app_label, homeappdir); - free(homeappdir); - return -1; - } - /* install signal handlers */ - siga.sa_flags = SA_SIGINFO | SA_NOCLDWAIT; - sigemptyset(&siga.sa_mask); - sigaddset(&siga.sa_mask, SIGCHLD); - siga.sa_sigaction = on_sigchld; - sigaction(SIGCHLD, &siga, NULL); - return 0; -} - diff --git a/src/afm-run.h b/src/afm-run.h deleted file mode 100644 index 1654832..0000000 --- a/src/afm-run.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright 2015, 2016, 2017 IoT.bzh - - author: José Bollo <jose.bollo@iot.bzh> - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -extern int afm_run_start(struct json_object *appli, enum afm_launch_mode mode, char **uri); -extern int afm_run_once(struct json_object *appli); -extern int afm_run_terminate(int runid); -extern int afm_run_pause(int runid); -extern int afm_run_resume(int runid); -extern struct json_object *afm_run_list(); -extern struct json_object *afm_run_state(int runid); - -extern int afm_run_init(); diff --git a/src/afm-system-daemon.c b/src/afm-system-daemon.c index 097913a..501a61c 100644 --- a/src/afm-system-daemon.c +++ b/src/afm-system-daemon.c @@ -31,7 +31,6 @@ #include "utils-json.h" #include "utils-systemd.h" #include "afm.h" -#include "afm-db.h" #include "wgt-info.h" #include "wgtpkg-install.h" #include "wgtpkg-uninstall.h" @@ -87,11 +86,9 @@ const char error_cant_start[] = "\"can't start\""; static void do_reloads() { -#ifndef LEGACY_MODE_WITHOUT_SYSTEMD /* enforce daemon reload */ systemd_daemon_reload(0); systemd_unit_restart_name(0, "sockets.target"); -#endif } static void on_install(struct sd_bus_message *smsg, struct json_object *req, void *unused) diff --git a/src/afm-user-daemon.c b/src/afm-user-daemon.c index 11a46de..057f23e 100644 --- a/src/afm-user-daemon.c +++ b/src/afm-user-daemon.c @@ -31,14 +31,8 @@ #include "utils-json.h" #include "utils-systemd.h" #include "afm.h" -#include "afm-launch-mode.h" -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD -# include "afm-db.h" -#include "afm-run.h" -#else -# include "afm-udb.h" +#include "afm-udb.h" #include "afm-urun.h" -#endif /* * name of the application @@ -61,16 +55,8 @@ static const char versionstr[] = * string for printing usage */ static const char usagestr[] = -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD - "usage: %s [-q] [-v] [-m mode] [-r rootdir]... [-a appdir]...\n" - "\n" - " -a appdir adds an application directory\n" - " -r rootdir adds a root directory of applications\n" - " -m mode set default launch mode (local or remote)\n" -#else "usage: %s [option(s)]\n" "\n" -#endif " -d run as a daemon\n" " -u addr address of user D-Bus to use\n" " -s addr address of system D-Bus to use\n" @@ -82,16 +68,8 @@ static const char usagestr[] = /* * Option definition for getopt_long */ -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD -static const char options_s[] = "hdqvVr:a:m:"; -static struct option options_l[] = { - { "root", required_argument, NULL, 'r' }, - { "application", required_argument, NULL, 'a' }, - { "mode", required_argument, NULL, 'm' }, -#else static const char options_s[] = "hdqvV"; static struct option options_l[] = { -#endif { "user-dbus", required_argument, NULL, 'u' }, { "system-dbus", required_argument, NULL, 's' }, { "daemon", no_argument, NULL, 'd' }, @@ -115,11 +93,7 @@ static struct jbus *jbuses[2]; /* * Handle to the database of applications */ -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD -static struct afm_db *afdb; -#else static struct afm_udb *afudb; -#endif /* * Returned error strings @@ -188,11 +162,7 @@ static void on_runnables(struct sd_bus_message *smsg, struct json_object *obj, v { struct json_object *resp; INFO("method runnables called"); -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD - resp = afm_db_application_list(afdb); -#else resp = afm_udb_applications_public(afudb); -#endif jbus_reply_j(smsg, resp); json_object_put(resp); } @@ -218,11 +188,7 @@ static void on_detail(struct sd_bus_message *smsg, struct json_object *obj, void /* wants details for appid */ INFO("method detail called for %s", appid); -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD - resp = afm_db_get_application_public(afdb, appid); -#else resp = afm_udb_get_application_public(afudb, appid); -#endif reply(smsg, resp, error_not_found); json_object_put(resp); } @@ -232,37 +198,23 @@ static void on_detail(struct sd_bus_message *smsg, struct json_object *obj, void */ static void on_start(struct sd_bus_message *smsg, struct json_object *obj, void *unused) { - const char *appid, *modestr; + const char *appid; char *uri; struct json_object *appli, *resp; int runid; char runidstr[20]; - enum afm_launch_mode mode; /* get the parameters */ - mode = invalid_launch_mode; - if (j_read_string(obj, &appid)) { - mode = get_default_launch_mode(); - } else if (j_read_string_at(obj, "id", &appid)) { - if (j_read_string_at(obj, "mode", &modestr)) { - mode = launch_mode_of_name(modestr); - } else { - mode = get_default_launch_mode(); + if (!j_read_string(obj, &appid)) { + if (!j_read_string_at(obj, "id", &appid)) { + jbus_reply_error_s(smsg, error_bad_request); + return; } } - if (!is_valid_launch_mode(mode)) { - jbus_reply_error_s(smsg, error_bad_request); - return; - } /* get the application */ - INFO("method start called for %s mode=%s", appid, - name_of_launch_mode(mode)); -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD - appli = afm_db_get_application(afdb, appid); -#else + INFO("method start called for %s", appid); appli = afm_udb_get_application_private(afudb, appid); -#endif if (appli == NULL) { jbus_reply_error_s(smsg, error_not_found); return; @@ -270,11 +222,7 @@ static void on_start(struct sd_bus_message *smsg, struct json_object *obj, void /* launch the application */ uri = NULL; -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD - runid = afm_run_start(appli, mode, &uri); -#else runid = afm_urun_start(appli); -#endif if (runid <= 0) { jbus_reply_error_s(smsg, error_cant_start); free(uri); @@ -295,11 +243,7 @@ static void on_start(struct sd_bus_message *smsg, struct json_object *obj, void && j_add_string(resp, "uri", uri)) jbus_reply_j(smsg, resp); else { -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD - afm_run_terminate(runid); -#else afm_urun_terminate(runid); -#endif jbus_reply_error_s(smsg, error_system); } json_object_put(resp); @@ -323,33 +267,21 @@ static void on_once(struct sd_bus_message *smsg, struct json_object *obj, void * /* get the application */ INFO("method once called for %s", appid); -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD - appli = afm_db_get_application(afdb, appid); -#else appli = afm_udb_get_application_private(afudb, appid); -#endif if (appli == NULL) { jbus_reply_error_s(smsg, error_not_found); return; } /* launch the application */ -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD - runid = afm_run_once(appli); -#else runid = afm_urun_once(appli); -#endif if (runid <= 0) { jbus_reply_error_s(smsg, error_cant_start); return; } /* returns the state */ -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD - resp = afm_run_state(runid); -#else resp = afm_urun_state(afudb, runid); -#endif reply(smsg, resp, error_not_found); json_object_put(resp); } @@ -361,11 +293,7 @@ static void on_pause(struct sd_bus_message *smsg, struct json_object *obj, void { int runid, status; if (onrunid(smsg, obj, "pause", &runid)) { -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD - status = afm_run_pause(runid); -#else status = afm_urun_pause(runid); -#endif reply_status(smsg, status, error_not_found); } } @@ -377,11 +305,7 @@ static void on_resume(struct sd_bus_message *smsg, struct json_object *obj, void { int runid, status; if (onrunid(smsg, obj, "resume", &runid)) { -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD - status = afm_run_resume(runid); -#else status = afm_urun_resume(runid); -#endif reply_status(smsg, status, error_not_found); } } @@ -411,11 +335,7 @@ static void on_terminate(struct sd_bus_message *smsg, struct json_object *obj, v { int runid, status; if (onrunid(smsg, obj, "terminate", &runid)) { -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD - status = afm_run_terminate(runid); -#else status = afm_urun_terminate(runid); -#endif reply_status(smsg, status, error_not_found); } } @@ -427,11 +347,7 @@ static void on_runners(struct sd_bus_message *smsg, struct json_object *obj, voi { struct json_object *resp; INFO("method runners called"); -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD - resp = afm_run_list(); -#else resp = afm_urun_list(afudb); -#endif jbus_reply_j(smsg, resp); json_object_put(resp); } @@ -444,11 +360,7 @@ static void on_state(struct sd_bus_message *smsg, struct json_object *obj, void int runid; struct json_object *resp; if (onrunid(smsg, obj, "state", &runid)) { -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD - resp = afm_run_state(runid); -#else resp = afm_urun_state(afudb, runid); -#endif reply(smsg, resp, error_not_found); json_object_put(resp); } @@ -502,17 +414,13 @@ static void on_uninstall(struct sd_bus_message *smsg, const char *msg, void *unu */ static void on_signal_changed(struct json_object *obj, void *unused) { -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD - /* update the database */ - afm_db_update_applications(afdb); -#else /* enforce daemon reload */ systemd_daemon_reload(1); systemd_unit_restart_name(1, "sockets.target"); /* update the database */ afm_udb_update(afudb); -#endif + /* re-propagate now */ jbus_send_signal_j(user_bus, "changed", obj); } @@ -576,9 +484,6 @@ fail: int main(int ac, char **av) { int i, daemon = 0, rc; -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD - enum afm_launch_mode mode; -#endif struct sd_event *evloop; struct sd_bus *sysbus, *usrbus; const char *sys_bus_addr, *usr_bus_addr; @@ -606,20 +511,6 @@ int main(int ac, char **av) case 'd': daemon = 1; break; -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD - case 'r': - break; - case 'a': - break; - case 'm': - mode = launch_mode_of_name(optarg); - if (!is_valid_launch_mode(mode)) { - ERROR("invalid mode '%s'", optarg); - return 1; - } - set_default_launch_mode(mode); - break; -#endif case 'u': usr_bus_addr = optarg; break; @@ -638,56 +529,12 @@ int main(int ac, char **av) /* init random generator */ srandom((unsigned int)time(NULL)); -#ifdef LEGACY_MODE_WITHOUT_SYSTEMD - /* init runners */ - if (afm_run_init()) { - ERROR("afm_run_init failed"); - return 1; - } - - /* init framework */ - afdb = afm_db_create(); - if (!afdb) { - ERROR("afm_db_create failed"); - return 1; - } - if (afm_db_add_root(afdb, FWK_APP_DIR)) { - ERROR("can't add root %s", FWK_APP_DIR); - return 1; - } - - /* second interpretation of arguments */ - optind = 1; - while ((i = getopt_long(ac, av, options_s, options_l, NULL)) >= 0) { - switch (i) { - case 'r': - if (afm_db_add_root(afdb, optarg)) { - ERROR("can't add root %s", optarg); - return 1; - } - break; - case 'a': - if (afm_db_add_application(afdb, optarg)) { - ERROR("can't add application %s", optarg); - return 1; - } - break; - } - } - - /* update the database */ - if (afm_db_update_applications(afdb)) { - ERROR("afm_update_applications failed"); - return 1; - } -#else /* init database */ afudb = afm_udb_create(0, 1, "afm-appli-"); if (!afudb) { ERROR("afm_udb_create failed"); return 1; } -#endif /* daemonize if requested */ if (daemon && daemonize()) { |