2 Copyright 2015, 2016, 2017 IoT.bzh
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.
25 #include <systemd/sd-bus.h>
26 #include <systemd/sd-event.h>
27 #include <json-c/json.h>
30 #include "utils-jbus.h"
31 #include "utils-json.h"
32 #include "utils-systemd.h"
36 #include "wgtpkg-install.h"
37 #include "wgtpkg-uninstall.h"
39 static const char appname[] = "afm-system-daemon";
40 static const char *rootdir = NULL;
45 "usage: %s [-q] [-v] [-r rootdir]\n"
47 " -r rootdir set root directory of applications\n"
48 " -d run as a daemon\n"
56 static struct option options[] = {
57 { "root", required_argument, NULL, 'r' },
58 { "daemon", no_argument, NULL, 'd' },
59 { "quiet", no_argument, NULL, 'q' },
60 { "verbose", no_argument, NULL, 'v' },
61 { "help", no_argument, NULL, 'h' },
65 static struct jbus *jbus;
67 const char error_nothing[] = "[]";
68 const char error_bad_request[] = "\"bad request\"";
69 const char error_not_found[] = "\"not found\"";
70 const char error_cant_start[] = "\"can't start\"";
72 static void do_reloads()
74 #ifndef LEGACY_MODE_WITHOUT_SYSTEMD
75 /* enforce daemon reload */
76 systemd_daemon_reload(0);
77 systemd_unit_restart_name(0, "sockets.target");
81 static void on_install(struct sd_bus_message *smsg, struct json_object *req, void *unused)
88 struct json_object *resp;
90 /* scan the request */
91 switch (json_object_get_type(req)) {
92 case json_type_string:
93 wgtfile = json_object_get_string(req);
98 case json_type_object:
99 wgtfile = j_string_at(req, "wgt", NULL);
100 if (wgtfile != NULL) {
101 root = j_string_at(req, "root", rootdir);
102 force = j_boolean_at(req, "force", 0);
103 reload = j_boolean_at(req, "reload", 1);
108 jbus_reply_error_s(smsg, error_bad_request);
112 /* install the widget */
113 ifo = install_widget(wgtfile, root, force);
115 jbus_reply_error_s(smsg, "\"installation failed\"");
117 /* reload if needed */
121 /* build the response */
122 resp = json_object_new_object();
123 if(!resp || !j_add_string(resp, "added", wgt_info_desc(ifo)->idaver))
124 jbus_reply_error_s(smsg, "\"out of memory but installed!\"");
126 jbus_send_signal_s(jbus, "changed", "true");
127 jbus_reply_j(smsg, resp);
132 json_object_put(resp);
136 static void on_uninstall(struct sd_bus_message *smsg, struct json_object *req, void *unused)
142 /* scan the request */
143 switch (json_object_get_type(req)) {
144 case json_type_string:
145 idaver = json_object_get_string(req);
148 case json_type_object:
149 idaver = j_string_at(req, "id", NULL);
150 if (idaver != NULL) {
151 root = j_string_at(req, "root", rootdir);
156 jbus_reply_error_s(smsg, error_bad_request);
160 /* install the widget */
161 rc = uninstall_widget(idaver, root);
163 jbus_reply_error_s(smsg, "\"uninstallation had error\"");
165 jbus_send_signal_s(jbus, "changed", "true");
166 jbus_reply_s(smsg, "true");
170 static int daemonize()
180 int main(int ac, char **av)
182 int i, daemon = 0, rc;
183 struct sd_event *evloop;
184 struct sd_bus *sysbus;
188 /* interpretation of arguments */
189 while ((i = getopt_long(ac, av, "hdqvr:", options, NULL)) >= 0) {
208 ERROR("duplicate definition of rootdir");
213 ERROR("missing argument value");
216 ERROR("unrecognized option");
221 /* check the rootdir */
223 rootdir = FWK_APP_DIR;
225 rootdir = realpath(rootdir, NULL);
226 if (rootdir == NULL) {
227 ERROR("out of memory");
231 if (chdir(rootdir)) {
232 ERROR("can't enter %s", rootdir);
237 if (daemon && daemonize()) {
238 ERROR("daemonization failed");
242 /* get systemd objects */
243 rc = sd_event_new(&evloop);
245 ERROR("can't create event loop");
248 rc = sd_bus_open_system(&sysbus);
250 ERROR("can't create system bus");
253 rc = sd_bus_attach_event(sysbus, evloop, 0);
255 ERROR("can't attach system bus to event loop");
260 jbus = create_jbus(sysbus, AFM_SYSTEM_DBUS_PATH);
262 ERROR("create_jbus failed");
265 if(jbus_add_service_j(jbus, "install", on_install, NULL)
266 || jbus_add_service_j(jbus, "uninstall", on_uninstall, NULL)) {
267 ERROR("adding services failed");
272 if (jbus_start_serving(jbus) < 0) {
273 ERROR("can't start server");
277 sd_event_run(evloop, (uint64_t)-1);