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);
107 jbus_reply_error_s(smsg, error_bad_request);
111 /* install the widget */
112 ifo = install_widget(wgtfile, root, force);
114 jbus_reply_error_s(smsg, "\"installation failed\"");
116 /* reload if needed */
120 /* build the response */
121 resp = json_object_new_object();
122 if(!resp || !j_add_string(resp, "added", wgt_info_desc(ifo)->idaver))
123 jbus_reply_error_s(smsg, "\"out of memory but installed!\"");
125 jbus_send_signal_s(jbus, "changed", "true");
126 jbus_reply_j(smsg, resp);
131 json_object_put(resp);
135 static void on_uninstall(struct sd_bus_message *smsg, struct json_object *req, void *unused)
141 /* scan the request */
142 switch (json_object_get_type(req)) {
143 case json_type_string:
144 idaver = json_object_get_string(req);
147 case json_type_object:
148 idaver = j_string_at(req, "id", NULL);
149 if (idaver != NULL) {
150 root = j_string_at(req, "root", rootdir);
154 jbus_reply_error_s(smsg, error_bad_request);
158 /* install the widget */
159 rc = uninstall_widget(idaver, root);
161 jbus_reply_error_s(smsg, "\"uninstallation had error\"");
163 jbus_send_signal_s(jbus, "changed", "true");
164 jbus_reply_s(smsg, "true");
168 static int daemonize()
178 int main(int ac, char **av)
180 int i, daemon = 0, rc;
181 struct sd_event *evloop;
182 struct sd_bus *sysbus;
186 /* interpretation of arguments */
187 while ((i = getopt_long(ac, av, "hdqvr:", options, NULL)) >= 0) {
206 ERROR("duplicate definition of rootdir");
211 ERROR("missing argument value");
214 ERROR("unrecognized option");
219 /* check the rootdir */
221 rootdir = FWK_APP_DIR;
223 rootdir = realpath(rootdir, NULL);
224 if (rootdir == NULL) {
225 ERROR("out of memory");
229 if (chdir(rootdir)) {
230 ERROR("can't enter %s", rootdir);
235 if (daemon && daemonize()) {
236 ERROR("daemonization failed");
240 /* get systemd objects */
241 rc = sd_event_new(&evloop);
243 ERROR("can't create event loop");
246 rc = sd_bus_open_system(&sysbus);
248 ERROR("can't create system bus");
251 rc = sd_bus_attach_event(sysbus, evloop, 0);
253 ERROR("can't attach system bus to event loop");
258 jbus = create_jbus(sysbus, AFM_SYSTEM_DBUS_PATH);
260 ERROR("create_jbus failed");
263 if(jbus_add_service_j(jbus, "install", on_install, NULL)
264 || jbus_add_service_j(jbus, "uninstall", on_uninstall, NULL)) {
265 ERROR("adding services failed");
270 if (jbus_start_serving(jbus) < 0) {
271 ERROR("can't start server");
275 sd_event_run(evloop, (uint64_t)-1);