4 author: José Bollo <jose.bollo@iot.bzh>
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
30 #include <sys/types.h>
32 extern char **environ;
35 #include "af-launch.h"
36 #include "secmgr-wrap.h"
43 static int launch_html(struct af_launch_desc *desc, struct launchparam *params);
44 static int launch_bin(struct af_launch_desc *desc, struct launchparam *params);
45 static int launch_qml(struct af_launch_desc *desc, struct launchparam *params);
47 static int launch_master(struct af_launch_desc *desc, struct launchparam *params, int fd, pid_t child);
51 int (*launcher)(struct af_launch_desc *desc, struct launchparam *params);
54 { "text/html", launch_html },
55 { "application/x-executable", launch_bin },
56 { "application/octet-stream", launch_bin },
57 { "text/vnd.qt.qml", launch_qml }
60 static void mksecret(char buffer[9])
62 snprintf(buffer, 9, "%08lX", (0xffffffff & random()));
67 static int port_ring = 12345;
69 if (port < 12345 || port > 15432)
75 int af_launch(struct af_launch_desc *desc, pid_t children[2])
77 char datadir[PATH_MAX];
84 struct launchparam params;
88 if (desc->type != NULL && *desc->type) {
89 nkl = sizeof known_launchers / sizeof * known_launchers;
90 while (ikl < nkl && strcmp(desc->type, known_launchers[ikl].type))
93 ERROR("type %s not found!", desc->type);
100 rc = snprintf(datadir, sizeof datadir, "%s/%s", desc->home, desc->tag);
101 if (rc < 0 || rc >= sizeof datadir) {
102 ERROR("overflow for datadir");
107 /* make the secret and port */
112 params.secret = secret;
114 /* prepare the pipes */
115 rc = pipe2(mpipe, O_CLOEXEC);
117 ERROR("error while calling pipe2: %m");
120 rc = pipe2(spipe, O_CLOEXEC);
122 ERROR("error while calling pipe2: %m");
128 /* fork the master child */
129 children[0] = fork();
130 if (children[0] < 0) {
131 ERROR("master fork failed: %m");
139 /********* in the parent process ************/
142 /* wait the ready signal (that transmit the slave pid) */
143 rc = read(mpipe[0], &children[1], sizeof children[1]);
145 ERROR("reading master pipe failed: %m");
151 assert(rc == sizeof children[1]);
152 /* start the child */
153 rc = write(spipe[1], "start", 5);
155 ERROR("writing slave pipe failed: %m");
164 /********* in the master child ************/
168 /* enter the process group */
171 ERROR("setpgid failed");
175 /* enter security mode */
176 rc = secmgr_prepare_exec(desc->tag);
178 ERROR("call to secmgr_prepare_exec failed: %m");
182 /* enter the datadirectory */
183 rc = mkdir(datadir, 0755);
184 if (rc && errno != EEXIST) {
185 ERROR("creation of datadir %s failed: %m", datadir);
190 ERROR("can't enter the datadir %s: %m", datadir);
194 /* fork the slave child */
195 children[1] = fork();
196 if (children[1] < 0) {
197 ERROR("slave fork failed: %m");
200 if (children[1] == 0) {
201 /********* in the slave child ************/
203 rc = read(spipe[0], message, sizeof message);
205 ERROR("reading slave pipe failed: %m");
208 rc = known_launchers[ikl].launcher(desc, ¶ms);
209 ERROR("slave launch failed: %m");
213 /********* still in the master child ************/
215 rc = launch_master(desc, ¶ms, mpipe[1], children[1]);
216 ERROR("master launch failed: %m");
220 static int launch_master(struct af_launch_desc *desc, struct launchparam *params, int fd, pid_t child)
224 argv[0] = "/usr/bin/echo";
225 (void)asprintf(&argv[1], "--alias=/icons:%s", FWK_ICON_DIR);
226 (void)asprintf(&argv[2], "--port=%d", params->port);
227 (void)asprintf(&argv[3], "--rootdir=%s", desc->path);
228 (void)asprintf(&argv[4], "--token=%s", params->secret);
231 rc = write(fd, &child, sizeof child);
233 ERROR("can't write master pipe: %m");
237 rc = execve(argv[0], argv, environ);
238 ERROR("failed to exec master %s: %m", argv[0]);
242 static int launch_html(struct af_launch_desc *desc, struct launchparam *params)
245 char *url = asprintf("http://localhost:%d/", params->port);
249 argv[0] = "/usr/bin/chromium";
250 (void)asprintf(&argv[1], "file://%s/%s", desc->path, desc->content);
252 rc = execve(argv[0], argv, environ);
253 ERROR("failed to exec slave %s: %m", argv[0]);
257 static int launch_bin(struct af_launch_desc *desc, struct launchparam *params)
259 ERROR("unimplemented launch_bin");
263 static int launch_qml(struct af_launch_desc *desc, struct launchparam *params)
265 ERROR("unimplemented launch_qml");