summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/af-launch.c221
1 files changed, 155 insertions, 66 deletions
diff --git a/src/af-launch.c b/src/af-launch.c
index 438dca6..ce42221 100644
--- a/src/af-launch.c
+++ b/src/af-launch.c
@@ -35,28 +35,145 @@ extern char **environ;
#include "af-launch.h"
#include "secmgr-wrap.h"
-struct launchparam {
- int port;
- const char *secret;
+/*
+%I icondir FWK_ICON_DIR
+%P port params->port
+%S secret params->secret
+%D datadir params->datadir
+%r rootdir desc->path
+%h homedir desc->home
+%t tag (smack label) desc->tag
+%a appid desc->appid
+%c content desc->content
+%m mime-type desc->type
+%n name desc->name
+%p plugins desc->plugins
+%W width desc->width
+%H height desc->height
+*/
+
+static const char *launch_master_args[] = {
+ "/usr/bin/echo",
+ "--alias=/icons:%I",
+ "--port=%P",
+ "--rootdir=%D",
+ "--token=%S",
+ NULL
};
-static int launch_html(struct af_launch_desc *desc, struct launchparam *params);
-static int launch_bin(struct af_launch_desc *desc, struct launchparam *params);
-static int launch_qml(struct af_launch_desc *desc, struct launchparam *params);
+static const char *launch_html_args[] = {
+ "/usr/bin/chromium",
+ "--single-process",
+ "--user-data-dir=%D",
+ "--data-path=%r",
+ "file://%r/%c",
+/*
+ "http://localhost:%P",
+*/
+ NULL
+};
+
+static const char *launch_bin_args[] = {
+ "/usr/bin/echo",
+ "BINARY",
+ NULL
+};
-static int launch_master(struct af_launch_desc *desc, struct launchparam *params, int fd, pid_t child);
+static const char *launch_qml_args[] = {
+ "/usr/bin/echo",
+ "QML",
+ NULL
+};
static struct {
const char *type;
- int (*launcher)(struct af_launch_desc *desc, struct launchparam *params);
+ const char **launch_args;
}
known_launchers[] = {
- { "text/html", launch_html },
- { "application/x-executable", launch_bin },
- { "application/octet-stream", launch_bin },
- { "text/vnd.qt.qml", launch_qml }
+ { "text/html", launch_html_args },
+ { "application/x-executable", launch_bin_args },
+ { "application/octet-stream", launch_bin_args },
+ { "text/vnd.qt.qml", launch_qml_args }
};
+struct launchparam {
+ int port;
+ const char *secret;
+ const char *datadir;
+};
+
+static char **instantiate_arguments(const char **args, struct af_launch_desc *desc, struct launchparam *params)
+{
+ const char **iter, *p, *v;
+ char *data, **result, port[20], width[20], height[20], mini[3], c;
+ int n, s, x;
+
+ /* init */
+ mini[0] = '%';
+ mini[2] = 0;
+
+ /* loop that either compute the size and build the result */
+ n = s = x = 0;
+ for (;;) {
+ iter = args;
+ n = 0;
+ while (*iter) {
+ p = *iter++;
+ if (x)
+ result[n] = data;
+ n++;
+ while((c = *p++) != 0) {
+ if (c != '%') {
+ if (x)
+ *data++ = c;
+ else
+ s++;
+ } else {
+ c = *p++;
+ switch (c) {
+ case 'I': v = FWK_ICON_DIR; break;
+ case 'P': if(!x) sprintf(port, "%d", params->port); v = port; break;
+ case 'S': v = params->secret; break;
+ case 'D': v = params->datadir; break;
+ case 'r': v = desc->path; break;
+ case 'h': v = desc->home; break;
+ case 't': v = desc->tag; break;
+ case 'a': v = desc->appid; break;
+ case 'c': v = desc->content; break;
+ case 'm': v = desc->type; break;
+ case 'n': v = desc->name; break;
+ case 'p': v = "" /*desc->plugins*/; break;
+ case 'W': if(!x) sprintf(width, "%d", desc->width); v = width; break;
+ case 'H': if(!x) sprintf(height, "%d", desc->height); v = height; break;
+ case '%': c = 0;
+ default: mini[1] = c; v = mini; break;
+ }
+ if (x)
+ data = stpcpy(data, v);
+ else
+ s += strlen(v);
+ }
+ }
+ if (x)
+ *data++ = 0;
+ else
+ s++;
+ }
+ if (x) {
+ result[n] = NULL;
+ return result;
+ }
+ /* allocation */
+ result = malloc((n+1)*sizeof(char*) + s);
+ if (result == NULL) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ data = (char*)(&result[n + 1]);
+ x = 1;
+ }
+}
+
static void mksecret(char buffer[9])
{
snprintf(buffer, 9, "%08lX", (0xffffffff & random()));
@@ -82,6 +199,7 @@ int af_launch(struct af_launch_desc *desc, pid_t children[2])
int mpipe[2];
int spipe[2];
struct launchparam params;
+ char **args;
/* what launcher ? */
ikl = 0;
@@ -110,6 +228,7 @@ int af_launch(struct af_launch_desc *desc, pid_t children[2])
params.port = port;
params.secret = secret;
+ params.datadir = datadir;
/* prepare the pipes */
rc = pipe2(mpipe, O_CLOEXEC);
@@ -205,65 +324,35 @@ int af_launch(struct af_launch_desc *desc, pid_t children[2])
ERROR("reading slave pipe failed: %m");
_exit(1);
}
- rc = known_launchers[ikl].launcher(desc, &params);
- ERROR("slave launch failed: %m");
+
+ args = instantiate_arguments(known_launchers[ikl].launch_args, desc, &params);
+ if (args == NULL) {
+ ERROR("out of memory in slave");
+ }
+ else {
+ rc = execve(args[0], args, environ);
+ ERROR("failed to exec slave %s: %m", args[0]);
+ }
_exit(1);
}
/********* still in the master child ************/
close(spipe[1]);
- rc = launch_master(desc, &params, mpipe[1], children[1]);
- ERROR("master launch failed: %m");
- _exit(1);
-}
-
-static int launch_master(struct af_launch_desc *desc, struct launchparam *params, int fd, pid_t child)
-{
- int rc;
- char *argv[6];
- argv[0] = "/usr/bin/echo";
- (void)asprintf(&argv[1], "--alias=/icons:%s", FWK_ICON_DIR);
- (void)asprintf(&argv[2], "--port=%d", params->port);
- (void)asprintf(&argv[3], "--rootdir=%s", desc->path);
- (void)asprintf(&argv[4], "--token=%s", params->secret);
- argv[5] = NULL;
-
- rc = write(fd, &child, sizeof child);
- if (rc < 0) {
- ERROR("can't write master pipe: %m");
- return -1;
+ args = instantiate_arguments(launch_master_args, desc, &params);
+ if (args == NULL) {
+ ERROR("out of memory in master");
}
- close(fd);
- rc = execve(argv[0], argv, environ);
- ERROR("failed to exec master %s: %m", argv[0]);
- return rc;
-}
-
-static int launch_html(struct af_launch_desc *desc, struct launchparam *params)
-{
-/*
- char *url = asprintf("http://localhost:%d/", params->port);
-*/
- int rc;
- char *argv[3];
- argv[0] = "/usr/bin/chromium";
- (void)asprintf(&argv[1], "file://%s/%s", desc->path, desc->content);
- argv[2] = NULL;
- rc = execve(argv[0], argv, environ);
- ERROR("failed to exec slave %s: %m", argv[0]);
- return rc;
-}
-
-static int launch_bin(struct af_launch_desc *desc, struct launchparam *params)
-{
- ERROR("unimplemented launch_bin");
- return -1;
-}
-
-static int launch_qml(struct af_launch_desc *desc, struct launchparam *params)
-{
- ERROR("unimplemented launch_qml");
- return -1;
+ else {
+ rc = write(mpipe[1], &children[1], sizeof children[1]);
+ if (rc < 0) {
+ ERROR("can't write master pipe: %m");
+ }
+ else {
+ close(mpipe[1]);
+ rc = execve(args[0], args, environ);
+ ERROR("failed to exec master %s: %m", args[0]);
+ }
+ }
+ _exit(1);
}
-