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.
27 #include "utils-jbus.h"
32 static const char appname[] = "afm-user-daemon";
37 "usage: %s [-q] [-v] [-r rootdir]... [-a appdir]...\n"
39 " -a appdir adds an application directory\n"
40 " -r rootdir adds a root directory of applications\n"
41 " -d run as a daemon\n"
49 static struct option options[] = {
50 { "root", required_argument, NULL, 'r' },
51 { "application", required_argument, NULL, 'a' },
52 { "daemon", no_argument, NULL, 'd' },
53 { "quiet", no_argument, NULL, 'q' },
54 { "verbose", no_argument, NULL, 'v' },
55 { "help", no_argument, NULL, 'h' },
59 static struct jbus *jbuses[2];
60 static struct afm_db *afdb;
62 const char error_nothing[] = "[]";
63 const char error_bad_request[] = "\"bad request\"";
64 const char error_not_found[] = "\"not found\"";
65 const char error_cant_start[] = "\"can't start\"";
66 const char error_system[] = "\"system error\"";
68 static const char *getappid(struct json_object *obj)
70 return json_type_string == json_object_get_type(obj) ? json_object_get_string(obj) : NULL;
73 static int getrunid(struct json_object *obj)
75 return json_type_int == json_object_get_type(obj) ? json_object_get_int(obj) : 0;
78 static void reply(struct jreq *jreq, struct json_object *resp, const char *errstr)
81 jbus_reply_j(jreq, resp);
83 jbus_reply_error_s(jreq, errstr);
86 static void reply_status(struct jreq *jreq, int status)
89 jbus_reply_error_s(jreq, error_not_found);
91 jbus_reply_s(jreq, "true");
94 static void on_runnables(struct jreq *jreq, struct json_object *obj)
96 struct json_object *resp = afm_db_application_list(afdb);
97 jbus_reply_j(jreq, resp);
98 json_object_put(resp);
101 static void on_detail(struct jreq *jreq, struct json_object *obj)
103 const char *appid = getappid(obj);
104 struct json_object *resp = afm_db_get_application_public(afdb, appid);
105 reply(jreq, resp, error_not_found);
106 json_object_put(resp);
109 static void on_start(struct jreq *jreq, struct json_object *obj)
112 struct json_object *appli;
116 appid = getappid(obj);
118 jbus_reply_error_s(jreq, error_bad_request);
120 appli = afm_db_get_application(afdb, appid);
122 jbus_reply_error_s(jreq, error_not_found);
124 runid = afm_run_start(appli);
126 jbus_reply_error_s(jreq, error_cant_start);
128 snprintf(runidstr, sizeof runidstr, "%d", runid);
129 runidstr[sizeof runidstr - 1] = 0;
130 jbus_reply_s(jreq, runidstr);
136 static void on_stop(struct jreq *jreq, struct json_object *obj)
138 int runid = getrunid(obj);
139 int status = afm_run_stop(runid);
140 reply_status(jreq, status);
143 static void on_continue(struct jreq *jreq, struct json_object *obj)
145 int runid = getrunid(obj);
146 int status = afm_run_continue(runid);
147 reply_status(jreq, status);
150 static void on_terminate(struct jreq *jreq, struct json_object *obj)
152 int runid = getrunid(obj);
153 int status = afm_run_terminate(runid);
154 reply_status(jreq, status);
157 static void on_runners(struct jreq *jreq, struct json_object *obj)
159 struct json_object *resp = afm_run_list();
160 jbus_reply_j(jreq, resp);
161 json_object_put(resp);
164 static void on_state(struct jreq *jreq, struct json_object *obj)
166 int runid = getrunid(obj);
167 struct json_object *resp = afm_run_state(runid);
168 reply(jreq, resp, error_not_found);
169 json_object_put(resp);
172 static void propagate(struct jreq *jreq, const char *msg, const char *method)
174 char *reply = jbus_call_ss_sync(jbuses[0], method, msg);
176 jbus_reply_s(jreq, reply);
178 jbus_reply_error_s(jreq, error_system);
181 static void on_install(struct jreq *jreq, const char *msg)
183 return propagate(jreq, msg, "install");
186 static void on_uninstall(struct jreq *jreq, const char *msg)
188 return propagate(jreq, msg, "uninstall");
191 static void on_signal_changed(struct json_object *obj)
193 /* update the database */
194 afm_db_update_applications(afdb);
196 jbus_send_signal_j(jbuses[1], "changed", obj);
199 static int daemonize()
209 int main(int ac, char **av)
215 /* first interpretation of arguments */
216 while ((i = getopt_long(ac, av, "hdqvr:a:", options, NULL)) >= 0) {
236 ERROR("missing argument value");
239 ERROR("unrecognized option");
244 /* init random generator */
245 srandom((unsigned int)time(NULL));
248 if (afm_run_init()) {
249 ERROR("afm_run_init failed");
254 afdb = afm_db_create();
256 ERROR("afm_create failed");
259 if (afm_db_add_root(afdb, FWK_APP_DIR)) {
260 ERROR("can't add root %s", FWK_APP_DIR);
264 /* second interpretation of arguments */
266 while ((i = getopt_long(ac, av, "hdqvr:a:", options, NULL)) >= 0) {
269 if (afm_db_add_root(afdb, optarg)) {
270 ERROR("can't add root %s", optarg);
275 if (afm_db_add_application(afdb, optarg)) {
276 ERROR("can't add application %s", optarg);
283 /* update the database */
284 if (afm_db_update_applications(afdb)) {
285 ERROR("afm_update_applications failed");
289 if (daemon && daemonize()) {
290 ERROR("daemonization failed");
295 jbuses[0] = create_jbus(0, AFM_SYSTEM_DBUS_PATH);
297 ERROR("create_jbus failed for system");
300 if(jbus_on_signal_j(jbuses[0], "changed", on_signal_changed)) {
301 ERROR("adding signal observer failed");
306 jbuses[1] = create_jbus(1, AFM_USER_DBUS_PATH);
308 ERROR("create_jbus failed");
311 if(jbus_add_service_j(jbuses[1], "runnables", on_runnables)
312 || jbus_add_service_j(jbuses[1], "detail", on_detail)
313 || jbus_add_service_j(jbuses[1], "start", on_start)
314 || jbus_add_service_j(jbuses[1], "terminate", on_terminate)
315 || jbus_add_service_j(jbuses[1], "stop", on_stop)
316 || jbus_add_service_j(jbuses[1], "continue", on_continue)
317 || jbus_add_service_j(jbuses[1], "runners", on_runners)
318 || jbus_add_service_j(jbuses[1], "state", on_state)
319 || jbus_add_service_s(jbuses[1], "install", on_install)
320 || jbus_add_service_s(jbuses[1], "uninstall", on_uninstall)) {
321 ERROR("adding services failed");
326 if (jbus_start_serving(jbuses[1])) {
327 ERROR("can't start server");
330 while (jbus_read_write_dispatch_multiple(jbuses, 2, -1, 20) >= 0);