diff options
author | Stef Walter <stefw@redhat.com> | 2014-01-10 08:58:12 +0100 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2014-02-24 11:14:59 +0100 |
commit | 769347ad4d35d43488eb98f980143495b0db415d (patch) | |
tree | 1613fff70e57d363ceda4f5d2d3d48efd87073a0 /src/sbus | |
parent | 3e7d7af1953410f3f009bf3b2e481a46fb80de83 (diff) | |
download | sssd-769347ad4d35d43488eb98f980143495b0db415d.tar.gz sssd-769347ad4d35d43488eb98f980143495b0db415d.tar.xz sssd-769347ad4d35d43488eb98f980143495b0db415d.zip |
sbus: Rework sbus to use interface metadata and vtables
Previous commits added support for interface metadata and
handler vtables. This commit ports sbus_dbus_connection to
use them.
Port the internal uses of dbus to use the new scheme in a
very minimal way. Further cleanup is possible here.
This commit provides basic definitions of the internal
dbus interfaces. The interfaces aren't fully defined, as the
handlers will continue to unpack manually, and often overload
DBus methods with different arguments (which is rather
unorthodox, but not the end of the world).
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
Reviewed-by: Simo Sorce <simo@redhat.com>
Diffstat (limited to 'src/sbus')
-rw-r--r-- | src/sbus/sssd_dbus.h | 11 | ||||
-rw-r--r-- | src/sbus/sssd_dbus_connection.c | 67 |
2 files changed, 43 insertions, 35 deletions
diff --git a/src/sbus/sssd_dbus.h b/src/sbus/sssd_dbus.h index e9e7c9867..7d00b94d0 100644 --- a/src/sbus/sssd_dbus.h +++ b/src/sbus/sssd_dbus.h @@ -74,18 +74,9 @@ struct sbus_vtable { #define DBUS_INTROSPECT_INTERFACE "org.freedesktop.DBus.Introspectable" #define DBUS_INTROSPECT_METHOD "Introspect" -#define SBUS_DEFAULT_VTABLE { NULL, sbus_message_handler, NULL, NULL, NULL, NULL } - -struct sbus_method { - const char *method; - sbus_msg_handler_fn fn; -}; - struct sbus_interface { - const char *interface; const char *path; - DBusObjectPathVTable vtable; - struct sbus_method *methods; + struct sbus_vtable *vtable; sbus_msg_handler_fn introspect_fn; }; diff --git a/src/sbus/sssd_dbus_connection.c b/src/sbus/sssd_dbus_connection.c index eb07b8d5b..d39f1c01f 100644 --- a/src/sbus/sssd_dbus_connection.c +++ b/src/sbus/sssd_dbus_connection.c @@ -25,10 +25,14 @@ #include "util/util.h" #include "sbus/sssd_dbus.h" #include "sbus/sssd_dbus_private.h" +#include "sbus/sssd_dbus_meta.h" /* Types */ struct dbus_ctx_list; +static DBusObjectPathVTable dbus_object_path_vtable = + { NULL, sbus_message_handler, NULL, NULL, NULL, NULL }; + struct sbus_interface_p { struct sbus_interface_p *prev, *next; struct sbus_connection *conn; @@ -394,6 +398,10 @@ static int sbus_reply_internal_error(DBusMessage *message, return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } +/* Looks up a vtable func, in a struct derived from struct sbus_vtable */ +#define VTABLE_FUNC(vtable, offset) \ + (*((void **)((char *)(vtable) + (offset)))) + /* messsage_handler * Receive messages and process them */ @@ -402,24 +410,26 @@ DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn, void *user_data) { struct sbus_interface_p *intf_p; - const char *method; + const char *msg_method; const char *path; const char *msg_interface; DBusMessage *reply = NULL; - int i, ret; - int found; + const struct sbus_method_meta *method; + const struct sbus_interface_meta *interface; + sbus_msg_handler_fn handler_fn; + int ret; if (!user_data) { return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } intf_p = talloc_get_type(user_data, struct sbus_interface_p); - method = dbus_message_get_member(message); - DEBUG(SSSDBG_TRACE_ALL, "Received SBUS method [%s]\n", method); + msg_method = dbus_message_get_member(message); + DEBUG(SSSDBG_TRACE_ALL, "Received SBUS method [%s]\n", msg_method); path = dbus_message_get_path(message); msg_interface = dbus_message_get_interface(message); - if (!method || !path || !msg_interface) + if (!msg_method || !path || !msg_interface) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* Validate the D-BUS path */ @@ -427,26 +437,33 @@ DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn, return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* Validate the method interface */ - if (strcmp(msg_interface, intf_p->intf->interface) == 0) { - found = 0; - for (i = 0; intf_p->intf->methods[i].method != NULL; i++) { - if (strcmp(method, intf_p->intf->methods[i].method) == 0) { - found = 1; - ret = intf_p->intf->methods[i].fn(message, intf_p->conn); - if (ret != EOK) { - return sbus_reply_internal_error(message, intf_p->conn); - } - break; - } - } - - if (!found) { + interface = intf_p->intf->vtable->meta; + if (strcmp(msg_interface, interface->name) == 0) { + handler_fn = NULL; + method = sbus_meta_find_method(interface, msg_method); + if (method && method->vtable_offset) + handler_fn = VTABLE_FUNC(intf_p->intf->vtable, method->vtable_offset); + + if (!method) { /* Reply DBUS_ERROR_UNKNOWN_METHOD */ DEBUG(SSSDBG_CRIT_FAILURE, - "No matching method found for %s.\n", method); + "No matching method found for %s.\n", msg_method); reply = dbus_message_new_error(message, DBUS_ERROR_UNKNOWN_METHOD, NULL); sbus_conn_send_reply(intf_p->conn, reply); dbus_message_unref(reply); + + } else if (!handler_fn) { + /* Reply DBUS_ERROR_NOT_SUPPORTED */ + DEBUG(SSSDBG_CRIT_FAILURE, + "No handler provided found for %s.\n", msg_method); + reply = dbus_message_new_error(message, DBUS_ERROR_NOT_SUPPORTED, NULL); + sbus_conn_send_reply(intf_p->conn, reply); + dbus_message_unref(reply); + + } else { + ret = handler_fn(message, intf_p->conn); + if (ret != EOK) + return sbus_reply_internal_error(message, intf_p->conn); } } else { @@ -454,7 +471,7 @@ DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn, * This is usually only useful for system bus connections */ if (strcmp(msg_interface, DBUS_INTROSPECT_INTERFACE) == 0 && - strcmp(method, DBUS_INTROSPECT_METHOD) == 0) + strcmp(msg_method, DBUS_INTROSPECT_METHOD) == 0) { if (intf_p->intf->introspect_fn) { /* If we have been asked for introspection data and we have @@ -483,7 +500,7 @@ int sbus_conn_add_interface(struct sbus_connection *conn, dbus_bool_t dbret; const char *path; - if (!conn || !intf || !intf->vtable.message_function) { + if (!conn || !intf || !intf->vtable || !intf->vtable->meta) { return EINVAL; } @@ -505,7 +522,7 @@ int sbus_conn_add_interface(struct sbus_connection *conn, DLIST_ADD(conn->intf_list, intf_p); dbret = dbus_connection_register_object_path(conn->dbus.conn, - path, &intf->vtable, intf_p); + path, &dbus_object_path_vtable, intf_p); if (!dbret) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not register object path to the connection.\n"); @@ -586,7 +603,7 @@ static void sbus_reconnect(struct tevent_context *ev, while (iter) { dbret = dbus_connection_register_object_path(conn->dbus.conn, iter->intf->path, - &iter->intf->vtable, + &dbus_object_path_vtable, iter); if (!dbret) { DEBUG(SSSDBG_FATAL_FAILURE, |