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.
28 #include "utils-jbus.h"
32 #include "wgtpkg-install.h"
34 static const char appname[] = "afm-system-daemon";
39 "usage: %s [-q] [-v] [-r rootdir]... [-a appdir]...\n"
41 " -a appdir adds an application directory\n"
42 " -r rootdir adds a root directory of applications\n"
43 " -d run as a daemon\n"
51 static struct option options[] = {
52 { "root", required_argument, NULL, 'r' },
53 { "application", required_argument, NULL, 'a' },
54 { "daemon", no_argument, NULL, 'd' },
55 { "quiet", no_argument, NULL, 'q' },
56 { "verbose", no_argument, NULL, 'v' },
57 { "help", no_argument, NULL, 'h' },
61 static struct jbus *jbus;
62 static struct afm_db *afdb;
64 const char error_nothing[] = "[]";
65 const char error_bad_request[] = "\"bad request\"";
66 const char error_not_found[] = "\"not found\"";
67 const char error_cant_start[] = "\"can't start\"";
69 static const char *getappid(struct json_object *obj)
71 return json_type_string == json_object_get_type(obj) ? json_object_get_string(obj) : NULL;
74 static void reply(struct jreq *jreq, struct json_object *resp, const char *errstr)
77 jbus_reply_j(jreq, resp);
79 jbus_reply_error_s(jreq, errstr);
82 static void on_runnables(struct jreq *jreq, struct json_object *obj)
84 struct json_object *resp = afm_db_application_list(afdb);
85 jbus_reply_j(jreq, resp);
86 json_object_put(resp);
89 static void on_detail(struct jreq *jreq, struct json_object *obj)
91 const char *appid = getappid(obj);
92 struct json_object *resp = afm_db_get_application_public(afdb, appid);
93 reply(jreq, resp, error_not_found);
94 json_object_put(resp);
97 static const char *j_get_string(struct json_object *obj, const char *key, const char *defval)
99 struct json_object *o;
100 return json_object_object_get_ex(obj, key, &o) && json_object_get_type(o) == json_type_string ? json_object_get_string(o) : defval;
103 static int j_get_boolean(struct json_object *obj, const char *key, int defval)
105 struct json_object *o;
106 return json_object_object_get_ex(obj, key, &o) && json_object_get_type(o) == json_type_boolean ? json_object_get_boolean(o) : defval;
109 static int json_add(struct json_object *obj, const char *key, struct json_object *val)
111 json_object_object_add(obj, key, val);
115 static int json_add_str(struct json_object *obj, const char *key, const char *val)
117 struct json_object *str = json_object_new_string (val ? val : "");
118 return str ? json_add(obj, key, str) : (errno = ENOMEM, -1);
121 static int json_add_int(struct json_object *obj, const char *key, int val)
123 struct json_object *v = json_object_new_int (val);
124 return v ? json_add(obj, key, v) : (errno = ENOMEM, -1);
127 static void on_install(struct jreq *jreq, struct json_object *req)
132 struct wgt_info *ifo;
133 struct json_object *resp;
135 /* scan the request */
136 switch (json_object_get_type(req)) {
137 case json_type_string:
138 wgtfile = json_object_get_string(req);
142 case json_type_object:
143 wgtfile = j_get_string(req, "wgt", NULL);
144 if (wgtfile != NULL) {
145 root = j_get_string(req, "root", FWK_APP_DIR);
146 force = j_get_boolean(req, "force", 0);
150 jbus_reply_error_s(jreq, error_bad_request);
154 /* install the widget */
155 ifo = install_widget(wgtfile, root, force);
157 jbus_reply_error_s(jreq, "\"installation failed\"");
161 /* build the response */
162 resp = json_object_new_object();
163 if(!resp || json_add_str(resp, "added", wgt_info_desc(ifo)->idaver)) {
164 json_object_put(resp);
166 jbus_reply_error_s(jreq, "\"out of memory but installed!\"");
171 /* update the current database */
172 afm_db_update_applications(afdb);
174 /* reply and propagate event */
175 jbus_reply_j(jreq, resp);
176 jbus_send_signal_j(jbus, "changed", resp);
177 json_object_put(resp);
180 static void on_uninstall(struct jreq *jreq, struct json_object *req)
182 jbus_reply_error_s(jreq, "\"not yet implemented\"");
185 static int daemonize()
195 int main(int ac, char **av)
201 /* first interpretation of arguments */
202 while ((i = getopt_long(ac, av, "hdqvr:a:", options, NULL)) >= 0) {
222 ERROR("missing argument value");
225 ERROR("unrecognized option");
231 afdb = afm_db_create();
233 ERROR("afm_create failed");
236 if (afm_db_add_root(afdb, FWK_APP_DIR)) {
237 ERROR("can't add root %s", FWK_APP_DIR);
241 /* second interpretation of arguments */
243 while ((i = getopt_long(ac, av, "hdqvr:a:", options, NULL)) >= 0) {
246 if (afm_db_add_root(afdb, optarg)) {
247 ERROR("can't add root %s", optarg);
252 if (afm_db_add_application(afdb, optarg)) {
253 ERROR("can't add application %s", optarg);
260 /* update the database */
261 if (afm_db_update_applications(afdb)) {
262 ERROR("afm_update_applications failed");
266 if (daemon && daemonize()) {
267 ERROR("daemonization failed");
272 jbus = create_jbus(0, AFM_SYSTEM_DBUS_PATH);
274 ERROR("create_jbus failed");
277 if(jbus_add_service_j(jbus, "runnables", on_runnables)
278 || jbus_add_service_j(jbus, "detail", on_detail)
279 || jbus_add_service_j(jbus, "install", on_install)
280 || jbus_add_service_j(jbus, "uninstall", on_uninstall)) {
281 ERROR("adding services failed");
286 if (jbus_start_serving(jbus)) {
287 ERROR("can't start server");
290 while (!jbus_read_write_dispatch(jbus, -1));