diff options
-rw-r--r-- | src/af-launch.c | 221 |
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, ¶ms); - ERROR("slave launch failed: %m"); + + args = instantiate_arguments(known_launchers[ikl].launch_args, desc, ¶ms); + 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, ¶ms, 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, ¶ms); + 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); } - |