aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--conf/CMakeLists.txt1
-rw-r--r--conf/afm-launch.conf26
-rw-r--r--src/afm-launch.c243
-rw-r--r--src/afm-launch.h1
-rw-r--r--src/afm-run.c5
6 files changed, 239 insertions, 38 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e8c98b4..48cb270 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -53,6 +53,7 @@ defstr(FWK_ICON_DIR "${afm_icondir}")
defstr(FWK_APP_DIR "${afm_appdir}")
defstr(FWK_USER_APP_DIR "${afm_user_appdir}")
defstr(WGTPKG_TRUSTED_CERT_DIR "${wgtpkg_trusted_cert_dir}")
+defstr(FWK_LAUNCH_CONF "${afm_confdir}/afm-launch.conf")
add_subdirectory(src)
add_subdirectory(conf)
diff --git a/conf/CMakeLists.txt b/conf/CMakeLists.txt
index 312b764..62bdf0f 100644
--- a/conf/CMakeLists.txt
+++ b/conf/CMakeLists.txt
@@ -27,4 +27,5 @@ install(FILES afm-system-daemon.conf DESTINATION ${SYSCONFDIR_DBUS_SYSTEM})
install(FILES afm-system-daemon.service DESTINATION ${UNITDIR_SYSTEM})
install(FILES afm-user-daemon.conf DESTINATION ${SYSCONFDIR_DBUS_USER})
install(FILES afm-user-daemon.service DESTINATION ${UNITDIR_USER})
+install(FILES afm-launch.conf DESTINATION ${afm_confdir})
diff --git a/conf/afm-launch.conf b/conf/afm-launch.conf
new file mode 100644
index 0000000..771569b
--- /dev/null
+++ b/conf/afm-launch.conf
@@ -0,0 +1,26 @@
+# %I icondir
+# %P port
+# %S secret
+# %D datadir
+# %r rootdir
+# %h homedir
+# %t tag (smack label)
+# %a appid
+# %c content
+# %m mime-type
+# %n name
+# %p plugins
+# %W width
+# %H height
+# %% %
+
+text/html
+ /usr/bin/afb-daemon --alias=/icons:%I --port=%P --rootdir=%r --token=%S --sessiondir=%D
+ /usr/bin/web-runtime http://localhost:%P/%c?token=%S
+
+application/x-executable
+ %r/%c
+
+text/vnd.qt.qml
+ /usr/bin/qt5/qmlscene -fullscreen -I %r -I %r/imports %r/%c
+
diff --git a/src/afm-launch.c b/src/afm-launch.c
index c1c6fdd..c55297a 100644
--- a/src/afm-launch.c
+++ b/src/afm-launch.c
@@ -52,6 +52,16 @@ extern char **environ;
%H height desc->height
*/
+#define DEFAULT_TYPE "text/html"
+
+const char separators[] = " \t\n";
+
+struct execdesc {
+ char *type;
+ char **execs[2];
+};
+
+#if 0
static const char *args_for_afb_daemon[] = {
"/usr/bin/afb-daemon",
"--alias=/icons:%I",
@@ -83,28 +93,185 @@ static const char *args_for_binary[] = {
NULL
};
-struct execdesc {
- const char *type;
- const char **master_args;
- const char **slave_args;
-};
-
static struct execdesc known_launchers[] = {
{ "text/html", args_for_afb_daemon, args_for_web_runtime },
{ "application/x-executable", args_for_binary, NULL },
- { "text/vnd.qt.qml", args_for_qmlviewer, NULL }
+ { "text/vnd.qt.qml", args_for_qmlviewer, NULL },
+ { NULL, NULL, NULL }
+};
+#endif
+
+struct launchers {
+ int count;
+ struct execdesc *descs;
};
+static struct launchers launchers = { 0, NULL };
+
struct launchparam {
int port;
const char *secret;
const char *datadir;
- const char **master_args;
- const char **slave_args;
+ const char **master;
+ const char **slave;
};
static gid_t groupid = 0;
+static int read_type(const char *buffer, const char *filepath, int line)
+{
+ size_t length;
+ int count;
+ struct execdesc *descs;
+ char *type;
+
+ /* check the type */
+ length = strcspn(buffer, separators);
+ assert(length);
+ if (buffer[length + strspn(buffer + length, separators)] != 0) {
+ ERROR("%s:%d: extra characters found after type", filepath, line);
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* allocates data */
+ type = strndup(buffer, length);
+ count = launchers.count + 1;
+ descs = realloc(launchers.descs, count * sizeof(struct execdesc));
+ if (descs == NULL || type == NULL) {
+ free(type);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ /* fill data */
+ launchers.descs = descs;
+ descs += count - 1;
+ descs->type = type;
+ descs->execs[0] = NULL;
+ descs->execs[1] = NULL;
+ launchers.count = count;
+ return 0;
+}
+
+static int read_args(const char *buffer, int bottom, int offset, const char *filepath, int line)
+{
+ char **vector, *args;
+ size_t index, len, length;
+ int count;
+
+ /* count */
+ count = 0;
+ length = index = 0;
+ while(buffer[index]) {
+ count++;
+ /* skips the spaces */
+ len = strcspn(buffer + index, separators);
+ length += len;
+ /* skips the spaces */
+ index += len;
+ index += strspn(buffer + index, separators);
+ }
+ /* allocates */
+ while (bottom < launchers.count) {
+ vector = malloc(length + count + (count + 1) * sizeof(char*));
+ if (vector == NULL) {
+ ERROR("%s:%d: out of memory", filepath, line);
+ return -1;
+ }
+ args = (char*)(vector + count + 1);
+ count = 0;
+ index = 0;
+ while(buffer[index]) {
+ /* skips the spaces */
+ len = strcspn(buffer + index, separators);
+ vector[count++] = args;
+ memcpy(args, buffer + index, len);
+ args += len;
+ index += len;
+ *args++ = 0;
+ /* skips the spaces */
+ len = strspn(buffer + index, separators);
+ index += len;
+ }
+ vector[count] = NULL;
+ launchers.descs[bottom++].execs[offset] = vector;
+ }
+ return 0;
+}
+
+static int read_launchers(FILE *file, const char *filepath)
+{
+ char buffer[4096];
+ int index, line, rc, bottom, offset, typed;
+
+ /* reads the file */
+ line = 0;
+ offset = 0;
+ typed = 0;
+ bottom = launchers.count;
+ while (fgets(buffer, sizeof buffer, file) != NULL) {
+ line++;
+
+ /* find start of line */
+ index = strspn(buffer, separators);
+
+ /* skip empty lines and comments */
+ if (buffer[index] == 0 || buffer[index] == '#')
+ continue;
+
+ if (index == 0) {
+ if (!typed)
+ bottom = launchers.count;
+ rc = read_type(buffer, filepath, line);
+ if (rc)
+ return rc;
+ if (!typed) {
+ typed = 1;
+ offset = 0;
+ }
+ } else if (!typed && !offset) {
+ ERROR("%s:%d: untyped launcher found", filepath, line);
+ errno = EINVAL;
+ return -1;
+ } else if (offset >= 2) {
+ ERROR("%s:%d: extra launcher found", filepath, line);
+ errno = EINVAL;
+ return -1;
+ } else {
+ rc = read_args(buffer + index, bottom, offset, filepath, line);
+ if (rc)
+ return rc;
+ offset++;
+ typed = 0;
+ }
+ }
+ if (ferror(file)) {
+ ERROR("%s:%d: error while reading, %m", filepath, line);
+ return -1;
+ }
+ return 0;
+}
+
+static int read_configuration_file(const char *filepath)
+{
+ int rc;
+ FILE *file;
+
+ /* opens the configuration file */
+ file = fopen(filepath, "r");
+ if (file == NULL) {
+ /* error */
+ ERROR("can't read file %s: %m", filepath);
+ rc = -1;
+ } else {
+ /* reads it */
+ rc = read_launchers(file, filepath);
+ fclose(file);
+ }
+ return rc;
+}
+
static char **instantiate_arguments(const char **args, struct afm_launch_desc *desc, struct launchparam *params)
{
const char **iter, *p, *v;
@@ -193,8 +360,6 @@ static int mkport()
return port;
}
-
-
static int launchexec1(struct afm_launch_desc *desc, pid_t children[2], struct launchparam *params)
{
int rc;
@@ -242,7 +407,7 @@ static int launchexec1(struct afm_launch_desc *desc, pid_t children[2], struct l
_exit(1);
}
- args = instantiate_arguments(params->master_args, desc, params);
+ args = instantiate_arguments(params->master, desc, params);
if (args == NULL) {
ERROR("out of memory in master");
}
@@ -358,7 +523,7 @@ static int launchexec2(struct afm_launch_desc *desc, pid_t children[2], struct l
_exit(1);
}
- args = instantiate_arguments(params->slave_args, desc, params);
+ args = instantiate_arguments(params->slave, desc, params);
if (args == NULL) {
ERROR("out of memory in slave");
}
@@ -371,7 +536,7 @@ static int launchexec2(struct afm_launch_desc *desc, pid_t children[2], struct l
/********* still in the master child ************/
close(spipe[1]);
- args = instantiate_arguments(params->master_args, desc, params);
+ args = instantiate_arguments(params->master, desc, params);
if (args == NULL) {
ERROR("out of memory in master");
}
@@ -389,39 +554,41 @@ static int launchexec2(struct afm_launch_desc *desc, pid_t children[2], struct l
_exit(1);
}
-static void afm_launch_init_group()
+int afm_launch_initialize()
{
- if (!groupid) {
- gid_t r, e, s;
- getresgid(&r, &e, &s);
- if (s && s != e)
- groupid = s;
- else
- groupid = -1;
- }
+ gid_t r, e, s;
+ getresgid(&r, &e, &s);
+ if (s && s != e)
+ groupid = s;
+ else
+ groupid = -1;
+ return read_configuration_file(FWK_LAUNCH_CONF);
}
int afm_launch(struct afm_launch_desc *desc, pid_t children[2])
{
char datadir[PATH_MAX];
- int ikl, nkl, rc;
+ int ikl, rc;
char secret[9];
struct launchparam params;
+ const char *type;
+
+ /* should be init */
+ assert(groupid != 0);
- /* static init */
- afm_launch_init_group();
+ /* init */
+ children[0] = 0;
+ children[1] = 0;
/* what launcher ? */
+ type = desc->type != NULL && *desc->type ? desc->type : DEFAULT_TYPE;
ikl = 0;
- if (desc->type != NULL && *desc->type) {
- nkl = sizeof known_launchers / sizeof * known_launchers;
- while (ikl < nkl && strcmp(desc->type, known_launchers[ikl].type))
- ikl++;
- if (ikl == nkl) {
- ERROR("type %s not found!", desc->type);
- errno = ENOENT;
- return -1;
- }
+ while (ikl < launchers.count && strcmp(type, launchers.descs[ikl].type))
+ ikl++;
+ if (ikl == launchers.count) {
+ ERROR("type %s not found!", type);
+ errno = ENOENT;
+ return -1;
}
/* prepare paths */
@@ -437,9 +604,9 @@ int afm_launch(struct afm_launch_desc *desc, pid_t children[2])
params.port = mkport();
params.secret = secret;
params.datadir = datadir;
- params.master_args = known_launchers[ikl].master_args;
- params.slave_args = known_launchers[ikl].slave_args;
+ params.master = (const char **)launchers.descs[ikl].execs[0];
+ params.slave = (const char **)launchers.descs[ikl].execs[1];
- return params.slave_args ? launchexec2(desc, children, &params) : launchexec1(desc, children, &params);
+ return params.slave ? launchexec2(desc, children, &params) : launchexec1(desc, children, &params);
}
diff --git a/src/afm-launch.h b/src/afm-launch.h
index 8990901..d7fcde2 100644
--- a/src/afm-launch.h
+++ b/src/afm-launch.h
@@ -29,4 +29,5 @@ struct afm_launch_desc {
int height;
};
+int afm_launch_initialize();
int afm_launch(struct afm_launch_desc *desc, pid_t children[2]);
diff --git a/src/afm-run.c b/src/afm-run.c
index 89d303f..b9e1e7c 100644
--- a/src/afm-run.c
+++ b/src/afm-run.c
@@ -429,6 +429,11 @@ int afm_run_init()
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);