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\"";
67 static const char *getappid(struct json_object *obj)
69 return json_type_string == json_object_get_type(obj) ? json_object_get_string(obj) : NULL;
72 static int getrunid(struct json_object *obj)
74 return json_type_int == json_object_get_type(obj) ? json_object_get_int(obj) : 0;
77 static void reply(struct jreq *jreq, struct json_object *resp, const char *errstr)
80 jbus_reply_j(jreq, resp);
82 jbus_reply_error_s(jreq, errstr);
85 static void reply_status(struct jreq *jreq, int status)
88 jbus_reply_error_s(jreq, error_not_found);
90 jbus_reply_s(jreq, "true");
93 static void on_runnables(struct jreq *jreq, struct json_object *obj)
95 struct json_object *resp = afm_db_application_list(afdb);
96 jbus_reply_j(jreq, resp);
97 json_object_put(resp);
100 static void on_detail(struct jreq *jreq, struct json_object *obj)
102 const char *appid = getappid(obj);
103 struct json_object *resp = afm_db_get_application_public(afdb, appid);
104 reply(jreq, resp, error_not_found);
105 json_object_put(resp);
108 static void on_start(struct jreq *jreq, struct json_object *obj)
111 struct json_object *appli;
115 appid = getappid(obj);
117 jbus_reply_error_s(jreq, error_bad_request);
119 appli = afm_db_get_application(afdb, appid);
121 jbus_reply_error_s(jreq, error_not_found);
123 runid = afm_run_start(appli);
125 jbus_reply_error_s(jreq, error_cant_start);
127 snprintf(runidstr, sizeof runidstr, "%d", runid);
128 runidstr[sizeof runidstr - 1] = 0;
129 jbus_reply_s(jreq, runidstr);
135 static void on_stop(struct jreq *jreq, struct json_object *obj)
137 int runid = getrunid(obj);
138 int status = afm_run_stop(runid);
139 reply_status(jreq, status);
142 static void on_continue(struct jreq *jreq, struct json_object *obj)
144 int runid = getrunid(obj);
145 int status = afm_run_continue(runid);
146 reply_status(jreq, status);
149 static void on_terminate(struct jreq *jreq, struct json_object *obj)
151 int runid = getrunid(obj);
152 int status = afm_run_terminate(runid);
153 reply_status(jreq, status);
156 static void on_runners(struct jreq *jreq, struct json_object *obj)
158 struct json_object *resp = afm_run_list();
159 jbus_reply_j(jreq, resp);
160 json_object_put(resp);
163 static void on_state(struct jreq *jreq, struct json_object *obj)
165 int runid = getrunid(obj);
166 struct json_object *resp = afm_run_state(runid);
167 reply(jreq, resp, error_not_found);
168 json_object_put(resp);
171 static void on_signal_changed(struct json_object *obj)
173 /* update the database */
174 afm_db_update_applications(afdb);
176 jbus_send_signal_j(jbuses[1], "changed", obj);
179 static int daemonize()
189 int main(int ac, char **av)
195 /* first interpretation of arguments */
196 while ((i = getopt_long(ac, av, "hdqvr:a:", options, NULL)) >= 0) {
216 ERROR("missing argument value");
219 ERROR("unrecognized option");
224 /* init random generator */
225 srandom((unsigned int)time(NULL));
228 if (afm_run_init()) {
229 ERROR("afm_run_init failed");
234 afdb = afm_db_create();
236 ERROR("afm_create failed");
239 if (afm_db_add_root(afdb, FWK_APP_DIR)) {
240 ERROR("can't add root %s", FWK_APP_DIR);
244 /* second interpretation of arguments */
246 while ((i = getopt_long(ac, av, "hdqvr:a:", options, NULL)) >= 0) {
249 if (afm_db_add_root(afdb, optarg)) {
250 ERROR("can't add root %s", optarg);
255 if (afm_db_add_application(afdb, optarg)) {
256 ERROR("can't add application %s", optarg);
263 /* update the database */
264 if (afm_db_update_applications(afdb)) {
265 ERROR("afm_update_applications failed");
269 if (daemon && daemonize()) {
270 ERROR("daemonization failed");
275 jbuses[0] = create_jbus(0, AFM_SYSTEM_DBUS_PATH);
277 ERROR("create_jbus failed for system");
280 if(jbus_on_signal_j(jbuses[0], "changed", on_signal_changed)) {
281 ERROR("adding signal observer failed");
286 jbuses[1] = create_jbus(1, AFM_USER_DBUS_PATH);
288 ERROR("create_jbus failed");
291 if(jbus_add_service_j(jbuses[1], "runnables", on_runnables)
292 || jbus_add_service_j(jbuses[1], "detail", on_detail)
293 || jbus_add_service_j(jbuses[1], "start", on_start)
294 || jbus_add_service_j(jbuses[1], "terminate", on_terminate)
295 || jbus_add_service_j(jbuses[1], "stop", on_stop)
296 || jbus_add_service_j(jbuses[1], "continue", on_continue)
297 || jbus_add_service_j(jbuses[1], "runners", on_runners)
298 || jbus_add_service_j(jbuses[1], "state", on_state)) {
299 ERROR("adding services failed");
304 if (jbus_start_serving(jbuses[1])) {
305 ERROR("can't start server");
308 while (jbus_read_write_dispatch_multiple(jbuses, 2, -1, 20) >= 0);