dbus: add introspection to midlevel paths

This commit is contained in:
Lennart Poettering 2010-10-13 03:03:31 +02:00
parent 37072578da
commit 2cccbca4fd
3 changed files with 148 additions and 2 deletions

2
TODO
View File

@ -56,8 +56,6 @@
* passphrase agent https://bugs.freedesktop.org/show_bug.cgi?id=30038
* support dbus introspection in mid-level object paths, i.e. in /org/freedesktop/systemd/units/.
* systemctl auto-pager a la git
* fsck setup

View File

@ -122,11 +122,72 @@ static DBusHandlerResult bus_job_message_handler(DBusConnection *connection, DBu
Manager *m = data;
Job *j;
int r;
DBusMessage *reply;
assert(connection);
assert(message);
assert(m);
if (streq(dbus_message_get_path(message), "/org/freedesktop/systemd1/job")) {
/* Be nice to gdbus and return introspection data for our mid-level paths */
if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
char *introspection = NULL;
FILE *f;
Iterator i;
size_t size;
if (!(reply = dbus_message_new_method_return(message)))
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. */
if (!(f = open_memstream(&introspection, &size)))
goto oom;
fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
"<node>\n", f);
fputs(BUS_INTROSPECTABLE_INTERFACE, f);
fputs(BUS_PEER_INTERFACE, f);
HASHMAP_FOREACH(j, m->jobs, i)
fprintf(f, "<node name=\"job/%lu\"/>", (unsigned long) j->id);
fputs("</node>\n", f);
if (ferror(f)) {
fclose(f);
free(introspection);
goto oom;
}
fclose(f);
if (!introspection)
goto oom;
if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) {
free(introspection);
goto oom;
}
free(introspection);
if (!dbus_connection_send(connection, reply, NULL))
goto oom;
dbus_message_unref(reply);
return DBUS_HANDLER_RESULT_HANDLED;
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
if ((r = manager_get_job_from_dbus_path(m, dbus_message_get_path(message), &j)) < 0) {
if (r == -ENOMEM)
@ -139,6 +200,12 @@ static DBusHandlerResult bus_job_message_handler(DBusConnection *connection, DBu
}
return bus_job_message_dispatch(j, connection, message);
oom:
if (reply)
dbus_message_unref(reply);
return DBUS_HANDLER_RESULT_NEED_MEMORY;
}
const DBusObjectPathVTable bus_job_vtable = {

View File

@ -454,11 +454,86 @@ static DBusHandlerResult bus_unit_message_handler(DBusConnection *connection, DB
Manager *m = data;
Unit *u;
int r;
DBusMessage *reply;
assert(connection);
assert(message);
assert(m);
if (streq(dbus_message_get_path(message), "/org/freedesktop/systemd1/unit")) {
/* Be nice to gdbus and return introspection data for our mid-level paths */
if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
char *introspection = NULL;
FILE *f;
Iterator i;
const char *k;
size_t size;
if (!(reply = dbus_message_new_method_return(message)))
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. */
if (!(f = open_memstream(&introspection, &size)))
goto oom;
fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
"<node>\n", f);
fputs(BUS_INTROSPECTABLE_INTERFACE, f);
fputs(BUS_PEER_INTERFACE, f);
HASHMAP_FOREACH_KEY(u, k, m->units, i) {
char *p;
if (k != u->meta.id)
continue;
if (!(p = bus_path_escape(k))) {
fclose(f);
free(introspection);
goto oom;
}
fprintf(f, "<node name=\"%s\"/>", p);
free(p);
}
fputs("</node>\n", f);
if (ferror(f)) {
fclose(f);
free(introspection);
goto oom;
}
fclose(f);
if (!introspection)
goto oom;
if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) {
free(introspection);
goto oom;
}
free(introspection);
if (!dbus_connection_send(connection, reply, NULL))
goto oom;
dbus_message_unref(reply);
return DBUS_HANDLER_RESULT_HANDLED;
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
if ((r = manager_get_unit_from_dbus_path(m, dbus_message_get_path(message), &u)) < 0) {
if (r == -ENOMEM)
@ -471,6 +546,12 @@ static DBusHandlerResult bus_unit_message_handler(DBusConnection *connection, DB
}
return bus_unit_message_dispatch(u, connection, message);
oom:
if (reply)
dbus_message_unref(reply);
return DBUS_HANDLER_RESULT_NEED_MEMORY;
}
const DBusObjectPathVTable bus_unit_vtable = {