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;
46 " %s version="AFM_VERSION"\n"
48 " Copyright (C) 2015, 2016, 2017 \"IoT.bzh\"\n"
49 " AFB comes with ABSOLUTELY NO WARRANTY.\n"
59 "usage: %s [-q] [-v] [-r rootdir]\n"
61 " -r rootdir set root directory of applications\n"
62 " -d run as a daemon\n"
71 static struct option options[] = {
72 { "root", required_argument, NULL, 'r' },
73 { "daemon", no_argument, NULL, 'd' },
74 { "quiet", no_argument, NULL, 'q' },
75 { "verbose", no_argument, NULL, 'v' },
76 { "help", no_argument, NULL, 'h' },
77 { "version", no_argument, NULL, 'V' },
81 static struct jbus *jbus;
83 const char error_nothing[] = "[]";
84 const char error_bad_request[] = "\"bad request\"";
85 const char error_not_found[] = "\"not found\"";
86 const char error_cant_start[] = "\"can't start\"";
88 static void do_reloads()
90 #ifndef LEGACY_MODE_WITHOUT_SYSTEMD
91 /* enforce daemon reload */
92 systemd_daemon_reload(0);
93 systemd_unit_restart_name(0, "sockets.target");
97 static void on_install(struct sd_bus_message *smsg, struct json_object *req, void *unused)
103 struct wgt_info *ifo;
104 struct json_object *resp;
106 /* scan the request */
107 switch (json_object_get_type(req)) {
108 case json_type_string:
109 wgtfile = json_object_get_string(req);
114 case json_type_object:
115 wgtfile = j_string_at(req, "wgt", NULL);
116 if (wgtfile != NULL) {
117 root = j_string_at(req, "root", rootdir);
118 force = j_boolean_at(req, "force", 0);
119 reload = j_boolean_at(req, "reload", 1);
124 jbus_reply_error_s(smsg, error_bad_request);
128 /* install the widget */
129 ifo = install_widget(wgtfile, root, force);
131 jbus_reply_error_s(smsg, "\"installation failed\"");
133 /* reload if needed */
137 /* build the response */
138 resp = json_object_new_object();
139 if(!resp || !j_add_string(resp, "added", wgt_info_desc(ifo)->idaver))
140 jbus_reply_error_s(smsg, "\"out of memory but installed!\"");
142 jbus_send_signal_s(jbus, "changed", "true");
143 jbus_reply_j(smsg, resp);
148 json_object_put(resp);
152 static void on_uninstall(struct sd_bus_message *smsg, struct json_object *req, void *unused)
158 /* scan the request */
159 switch (json_object_get_type(req)) {
160 case json_type_string:
161 idaver = json_object_get_string(req);
164 case json_type_object:
165 idaver = j_string_at(req, "id", NULL);
166 if (idaver != NULL) {
167 root = j_string_at(req, "root", rootdir);
172 jbus_reply_error_s(smsg, error_bad_request);
176 /* install the widget */
177 rc = uninstall_widget(idaver, root);
179 jbus_reply_error_s(smsg, "\"uninstallation had error\"");
181 jbus_send_signal_s(jbus, "changed", "true");
182 jbus_reply_s(smsg, "true");
186 static int daemonize()
196 int main(int ac, char **av)
198 int i, daemon = 0, rc;
199 struct sd_event *evloop;
200 struct sd_bus *sysbus;
204 /* interpretation of arguments */
205 while ((i = getopt_long(ac, av, "hdqvVr:", options, NULL)) >= 0) {
227 ERROR("duplicate definition of rootdir");
232 ERROR("missing argument value");
235 ERROR("unrecognized option");
240 /* check the rootdir */
242 rootdir = FWK_APP_DIR;
244 rootdir = realpath(rootdir, NULL);
245 if (rootdir == NULL) {
246 ERROR("out of memory");
250 if (chdir(rootdir)) {
251 ERROR("can't enter %s", rootdir);
256 if (daemon && daemonize()) {
257 ERROR("daemonization failed");
261 /* get systemd objects */
262 rc = sd_event_new(&evloop);
264 ERROR("can't create event loop");
267 rc = sd_bus_open_system(&sysbus);
269 ERROR("can't create system bus");
272 rc = sd_bus_attach_event(sysbus, evloop, 0);
274 ERROR("can't attach system bus to event loop");
279 jbus = create_jbus(sysbus, AFM_SYSTEM_DBUS_PATH);
281 ERROR("create_jbus failed");
284 if(jbus_add_service_j(jbus, "install", on_install, NULL)
285 || jbus_add_service_j(jbus, "uninstall", on_uninstall, NULL)) {
286 ERROR("adding services failed");
291 if (jbus_start_serving(jbus) < 0) {
292 ERROR("can't start server");
296 sd_event_run(evloop, (uint64_t)-1);