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"
35 #include "wgtpkg-install.h"
36 #include "wgtpkg-uninstall.h"
38 static const char appname[] = "afm-system-daemon";
39 static const char *rootdir = NULL;
45 " %s version="AFM_VERSION"\n"
47 " Copyright (C) 2015, 2016, 2017 \"IoT.bzh\"\n"
48 " AFB comes with ABSOLUTELY NO WARRANTY.\n"
58 "usage: %s [-q] [-v] [-r rootdir]\n"
60 " -r rootdir set root directory of applications\n"
61 " -d run as a daemon\n"
70 static struct option options[] = {
71 { "root", required_argument, NULL, 'r' },
72 { "daemon", no_argument, NULL, 'd' },
73 { "quiet", no_argument, NULL, 'q' },
74 { "verbose", no_argument, NULL, 'v' },
75 { "help", no_argument, NULL, 'h' },
76 { "version", no_argument, NULL, 'V' },
80 static struct jbus *jbus;
82 const char error_nothing[] = "[]";
83 const char error_bad_request[] = "\"bad request\"";
84 const char error_not_found[] = "\"not found\"";
85 const char error_cant_start[] = "\"can't start\"";
87 static void do_reloads()
89 /* enforce daemon reload */
90 systemd_daemon_reload(0);
91 systemd_unit_restart_name(0, "sockets.target");
94 static void on_install(struct sd_bus_message *smsg, struct json_object *req, void *unused)
100 struct wgt_info *ifo;
101 struct json_object *resp;
103 /* scan the request */
104 switch (json_object_get_type(req)) {
105 case json_type_string:
106 wgtfile = json_object_get_string(req);
111 case json_type_object:
112 wgtfile = j_string_at(req, "wgt", NULL);
113 if (wgtfile != NULL) {
114 root = j_string_at(req, "root", rootdir);
115 force = j_boolean_at(req, "force", 0);
116 reload = j_boolean_at(req, "reload", 1);
121 jbus_reply_error_s(smsg, error_bad_request);
125 /* install the widget */
126 ifo = install_widget(wgtfile, root, force);
128 jbus_reply_error_s(smsg, "\"installation failed\"");
130 /* reload if needed */
134 /* build the response */
135 resp = json_object_new_object();
136 if(!resp || !j_add_string(resp, "added", wgt_info_desc(ifo)->idaver))
137 jbus_reply_error_s(smsg, "\"out of memory but installed!\"");
139 jbus_send_signal_s(jbus, "changed", "true");
140 jbus_reply_j(smsg, resp);
145 json_object_put(resp);
149 static void on_uninstall(struct sd_bus_message *smsg, struct json_object *req, void *unused)
155 /* scan the request */
156 switch (json_object_get_type(req)) {
157 case json_type_string:
158 idaver = json_object_get_string(req);
161 case json_type_object:
162 idaver = j_string_at(req, "id", NULL);
163 if (idaver != NULL) {
164 root = j_string_at(req, "root", rootdir);
169 jbus_reply_error_s(smsg, error_bad_request);
173 /* install the widget */
174 rc = uninstall_widget(idaver, root);
176 jbus_reply_error_s(smsg, "\"uninstallation had error\"");
178 jbus_send_signal_s(jbus, "changed", "true");
179 jbus_reply_s(smsg, "true");
183 static int daemonize()
193 int main(int ac, char **av)
195 int i, daemon = 0, rc;
196 struct sd_event *evloop;
197 struct sd_bus *sysbus;
201 /* interpretation of arguments */
202 while ((i = getopt_long(ac, av, "hdqvVr:", options, NULL)) >= 0) {
224 ERROR("duplicate definition of rootdir");
229 ERROR("missing argument value");
232 ERROR("unrecognized option");
237 /* check the rootdir */
239 rootdir = FWK_APP_DIR;
241 rootdir = realpath(rootdir, NULL);
242 if (rootdir == NULL) {
243 ERROR("out of memory");
247 if (chdir(rootdir)) {
248 ERROR("can't enter %s", rootdir);
253 if (daemon && daemonize()) {
254 ERROR("daemonization failed");
258 /* get systemd objects */
259 rc = sd_event_new(&evloop);
261 ERROR("can't create event loop");
264 rc = sd_bus_open_system(&sysbus);
266 ERROR("can't create system bus");
269 rc = sd_bus_attach_event(sysbus, evloop, 0);
271 ERROR("can't attach system bus to event loop");
276 jbus = create_jbus(sysbus, AFM_SYSTEM_DBUS_PATH);
278 ERROR("create_jbus failed");
281 if(jbus_add_service_j(jbus, "install", on_install, NULL)
282 || jbus_add_service_j(jbus, "uninstall", on_uninstall, NULL)) {
283 ERROR("adding services failed");
288 if (jbus_start_serving(jbus) < 0) {
289 ERROR("can't start server");
293 sd_event_run(evloop, (uint64_t)-1);