dbus-manager.c revision 47be870bd83fb3719dffc3ee9348a409ab762a14
/*-*- Mode: C; c-basic-offset: 8 -*-*/
/***
This file is part of systemd.
Copyright 2010 Lennart Poettering
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <errno.h>
#include "dbus.h"
#include "log.h"
#define INTROSPECTION_BEGIN \
"<node>" \
" <interface name=\"org.freedesktop.systemd1\">" \
" <method name=\"GetUnit\">" \
" <arg name=\"name\" type=\"s\" direction=\"in\"/>" \
" <arg name=\"unit\" type=\"o\" direction=\"out\"/>" \
" </method>" \
" <method name=\"LoadUnit\">" \
" <arg name=\"name\" type=\"s\" direction=\"in\"/>" \
" <arg name=\"unit\" type=\"o\" direction=\"out\"/>" \
" </method>" \
" <method name=\"GetJob\">" \
" <arg name=\"id\" type=\"u\" direction=\"in\"/>" \
" <arg name=\"unit\" type=\"o\" direction=\"out\"/>" \
" </method>" \
" <method name=\"ClearJobs\"/>" \
" <method name=\"ListUnits\">" \
" <arg name=\"units\" type=\"a(ssssouso)\" direction=\"out\"/>" \
" </method>" \
" <method name=\"ListJobs\">" \
" <arg name=\"jobs\" type=\"a(usssoo)\" direction=\"out\"/>" \
" </method>" \
" </interface>" \
#define INTROSPECTION_END \
"</node>"
static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, DBusMessage *message, void *data) {
int r;
assert(m);
log_debug("Got D-Bus request: %s.%s() on %s",
const char *name;
Unit *u;
if (!dbus_message_get_args(
&error,
if (!(u = manager_get_unit(m, name)))
goto oom;
if (!(path = unit_dbus_path(u)))
goto oom;
if (!dbus_message_append_args(
goto oom;
const char *name;
Unit *u;
if (!dbus_message_get_args(
&error,
if ((r = manager_load_unit(m, name, &u)) < 0)
goto oom;
if (!(path = unit_dbus_path(u)))
goto oom;
if (!dbus_message_append_args(
goto oom;
Job *j;
if (!dbus_message_get_args(
&error,
if (!(j = manager_get_job(m, id)))
goto oom;
if (!(path = job_dbus_path(j)))
goto oom;
if (!dbus_message_append_args(
goto oom;
goto oom;
Iterator i;
Unit *u;
const char *k;
goto oom;
goto oom;
HASHMAP_FOREACH_KEY(u, k, m->units, i) {
if (k != id)
continue;
goto oom;
description = unit_description(u);
if (!(u_path = unit_dbus_path(u)))
goto oom;
goto oom;
}
} else {
job_id = 0;
job_type = "";
}
goto oom;
}
goto oom;
}
goto oom;
Iterator i;
Job *j;
goto oom;
goto oom;
HASHMAP_FOREACH(j, m->jobs, i) {
goto oom;
if (!(j_path = job_dbus_path(j)))
goto oom;
goto oom;
}
goto oom;
}
goto oom;
}
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
char *introspection = NULL;
FILE *f;
Iterator i;
Unit *u;
Job *j;
const char *k;
goto oom;
/* We roll our own introspection code here, instead of
* relying on bus_default_message_handler() because we
* need to generate our introspection string
* dynamically. */
goto oom;
fputs(INTROSPECTION_BEGIN, f);
HASHMAP_FOREACH_KEY(u, k, m->units, i) {
char *p;
if (k != unit_id(u))
continue;
if (!(p = bus_path_escape(k))) {
fclose(f);
goto oom;
}
fprintf(f, "<node name=\"unit/%s\"/>", p);
free(p);
}
HASHMAP_FOREACH(j, m->jobs, i)
fputs(INTROSPECTION_END, f);
if (ferror(f)) {
fclose(f);
goto oom;
}
fclose(f);
if (!introspection)
goto oom;
goto oom;
}
} else
if (reply) {
goto oom;
}
return DBUS_HANDLER_RESULT_HANDLED;
oom:
if (reply)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
}
const DBusObjectPathVTable bus_manager_vtable = {
};