diff options
author | Andrey Borzenkov <arvidjaar@gmail.com> | 2011-03-06 19:17:02 +0300 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2011-03-07 02:17:31 +0100 |
commit | c826cda421f0272275342173e16250adcdf6fbd4 (patch) | |
tree | d9b8ad25728a1958b6615738e083768bf764e15e /src/dbus.c | |
parent | b4353094e5097c0cb149b5adcffe2a6ba9240283 (diff) |
add org.freedesktop.DBus.Properies.Set method
The patch adds framework for processing Set requests on properties
and as first consumers allows setting of LogTarget and LogLevel on
interface org.freedesktop.systemd1.Manager of org.freedesktop.systemd1.
The code should be generic enough to allow processing of any
property on other objects and interfaces as well.
No systemctl visible interface is added so far. The LogTarget and
LogLevel are meant for debugging in the first place; user interface
can be added if other usage emerge.
Set on systemwide systemd is restricted to root; I am not sure
how session level access is controlled.
Diffstat (limited to 'src/dbus.c')
-rw-r--r-- | src/dbus.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/dbus.c b/src/dbus.c index 965a3e2f21..5a4750d6b9 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -1316,6 +1316,58 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBu if (!dbus_message_iter_close_container(&iter, &sub)) goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Set") && properties) { + const char *interface, *property; + DBusMessageIter iter; + const BusProperty *p; + + if (!dbus_message_iter_init(message, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return bus_send_error_reply(m, c, message, NULL, -EINVAL); + + dbus_message_iter_get_basic(&iter, &interface); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return bus_send_error_reply(m, c, message, NULL, -EINVAL); + + dbus_message_iter_get_basic(&iter, &property); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT || + dbus_message_iter_has_next(&iter)) + return bus_send_error_reply(m, c, message, NULL, -EINVAL); + + for (p = properties; p->property; p++) + if (streq(p->interface, interface) && streq(p->property, property)) + break; + + if (p->set) { + DBusMessageIter sub; + char *sig; + + dbus_message_iter_recurse(&iter, &sub); + + if (!(sig = dbus_message_iter_get_signature(&sub))) + goto oom; + + if (!streq(sig, p->signature)) { + dbus_free(sig); + return bus_send_error_reply(m, c, message, NULL, -EINVAL); + } + + dbus_free(sig); + + if ((r = p->set(m, &sub, property)) < 0) { + if (r == -ENOMEM) + goto oom; + return bus_send_error_reply(m, c, message, NULL, r); + } + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + } else + return bus_send_error_reply(m, c, message, NULL, -EINVAL); } if (reply) { |