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 *jbus;
60 static struct jbus *jbusys;
61 static struct afm_db *afdb;
63 const char error_nothing[] = "[]";
64 const char error_bad_request[] = "\"bad request\"";
65 const char error_not_found[] = "\"not found\"";
66 const char error_cant_start[] = "\"can't start\"";
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 on_signal_changed(struct json_object *obj)
174 /* update the database */
175 afm_db_update_applications(afdb);
177 jbus_send_signal_j(jbus, "changed", obj);
180 static int daemonize()
190 int main(int ac, char **av)
196 /* first interpretation of arguments */
197 while ((i = getopt_long(ac, av, "hdqvr:a:", options, NULL)) >= 0) {
217 ERROR("missing argument value");
220 ERROR("unrecognized option");
225 /* init random generator */
226 srandom((unsigned int)time(NULL));
229 if (afm_run_init()) {
230 ERROR("afm_run_init failed");
235 afdb = afm_db_create();
237 ERROR("afm_create failed");
240 if (afm_db_add_root(afdb, FWK_APP_DIR)) {
241 ERROR("can't add root %s", FWK_APP_DIR);
245 /* second interpretation of arguments */
247 while ((i = getopt_long(ac, av, "hdqvr:a:", options, NULL)) >= 0) {
250 if (afm_db_add_root(afdb, optarg)) {
251 ERROR("can't add root %s", optarg);
256 if (afm_db_add_application(afdb, optarg)) {
257 ERROR("can't add application %s", optarg);
264 /* update the database */
265 if (afm_db_update_applications(afdb)) {
266 ERROR("afm_update_applications failed");
270 if (daemon && daemonize()) {
271 ERROR("daemonization failed");
276 jbusys = create_jbus(0, AFM_SYSTEM_DBUS_PATH);
278 ERROR("create_jbus failed for system");
281 if(jbus_on_signal_j(jbusys, "changed", on_signal_changed)) {
282 ERROR("adding signal observer failed");
287 jbus = create_jbus(1, AFM_USER_DBUS_PATH);
289 ERROR("create_jbus failed");
292 if(jbus_add_service_j(jbus, "runnables", on_runnables)
293 || jbus_add_service_j(jbus, "detail", on_detail)
294 || jbus_add_service_j(jbus, "start", on_start)
295 || jbus_add_service_j(jbus, "terminate", on_terminate)
296 || jbus_add_service_j(jbus, "stop", on_stop)
297 || jbus_add_service_j(jbus, "continue", on_continue)
298 || jbus_add_service_j(jbus, "runners", on_runners)
299 || jbus_add_service_j(jbus, "state", on_state)) {
300 ERROR("adding services failed");
305 if (jbus_start_serving(jbus)) {
306 ERROR("can't start server");
309 while (!jbus_read_write_dispatch(jbus, -1));