From 6fe2bfce9fb9bb1564be8257cccc52bcec589de4 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 24 Oct 2008 19:09:44 +0200 Subject: D-BUS integration style changes. Rework interfaces a bit to simplify and uniform function names so that they use a well defined namespace (sssd_*). Simplify headers file, split them into a private and a public one only. Make static all file private functions. Rename sssd_dbus_client.c to sssd_dbus_connection.c to reflect it's function, as it is is used by both a server and a client. Introduce a function table to know where to dipatch messages. Fix coding style issues, and start pointing out where clean-up fucntions are missing. --- server/dbus/sssd_dbus_server.c | 300 ++++++++++++++++++++++++++++------------- 1 file changed, 209 insertions(+), 91 deletions(-) (limited to 'server/dbus/sssd_dbus_server.c') diff --git a/server/dbus/sssd_dbus_server.c b/server/dbus/sssd_dbus_server.c index 288a3333..113866fa 100644 --- a/server/dbus/sssd_dbus_server.c +++ b/server/dbus/sssd_dbus_server.c @@ -19,73 +19,50 @@ along with this program. If not, see . */ #include -#include "dbus/dbus.h" -#include "monitor.h" -#include "dbus/sssd_dbus_common.h" -#include "dbus/sssd_dbus_server.h" -#include "dbus/sssd_dbus_client.h" #include "events.h" #include "util/util.h" +#include "dbus/dbus.h" +#include "dbus/sssd_dbus.h" +#include "dbus/sssd_dbus_private.h" + +/* Types */ +struct dbus_server_toplevel_context { + DBusServer *server; + struct sssd_dbus_ctx *sd_ctx; +}; + +struct dbus_server_watch_context { + DBusWatch *watch; + int fd; + struct fd_event *fde; + struct dbus_server_toplevel_context *top; +}; + +struct dbus_server_timeout_context { + DBusTimeout *timeout; + struct timed_event *te; + struct dbus_server_toplevel_context *top; +}; /* - * integrate_server_with_event_loop - * Set up a D-BUS server to use the libevents mainloop - * for handling file descriptor and timed events + * dbus_server_read_write_handler + * Callback for D-BUS to handle messages on a file-descriptor */ -int integrate_server_with_event_loop(struct event_context *event_ctx, - DBusServer *dbus_server, - void(*server_connection_setup)(DBusConnection *conn, struct event_context *)) { - struct dbus_server_toplevel_context *dt_ctx; - dt_ctx = talloc_zero(event_ctx, struct dbus_server_toplevel_context); - dt_ctx->ev = event_ctx; - dt_ctx->server = dbus_server; - dt_ctx->server_connection_setup = server_connection_setup; - - /* Set up D-BUS new connection handler */ - dbus_server_set_new_connection_function(dt_ctx->server, - new_connection_callback, dt_ctx, NULL); - - /* Set up DBusWatch functions */ - if (!dbus_server_set_watch_functions(dt_ctx->server, add_server_watch, - remove_watch, toggle_server_watch, dt_ctx, NULL)) { - DEBUG(0,("Error setting up D-BUS server watch functions")); - return -1; - } +static void dbus_server_read_write_handler(struct event_context *ev, + struct fd_event *fde, + uint16_t flags, void *data) +{ + struct dbus_server_watch_context *svw_ctx; + svw_ctx = talloc_get_type(data, struct dbus_server_watch_context); - /* Set up DBusTimeout functions */ - if (!dbus_server_set_timeout_functions(dt_ctx->server, add_server_timeout, - remove_timeout, toggle_server_timeout, dt_ctx, NULL)) { - DEBUG(0,("Error setting up D-BUS server timeout functions")); - return -1; + dbus_server_ref(svw_ctx->top->server); + if (flags & EVENT_FD_READ) { + dbus_watch_handle(svw_ctx->watch, DBUS_WATCH_READABLE); } - - return 0; -} - -/* - * new_connection_callback - * Actions to be run upon each new client connection - * Must either perform dbus_connection_ref() on the - * new connection or else close the connection with - * dbus_connection_close() - */ -void new_connection_callback(DBusServer *server, - DBusConnection *new_connection, void *data) { - - struct dbus_server_toplevel_context *dst_ctx; - dst_ctx = talloc_get_type(data,struct dbus_server_toplevel_context); - - if(integrate_connection_with_event_loop(dst_ctx->ev,new_connection) != 0) { - dbus_connection_close(new_connection); - DEBUG(0,("Closing connection (failed setup)")); - return; + if (flags & EVENT_FD_WRITE) { + dbus_watch_handle(svw_ctx->watch, DBUS_WATCH_WRITABLE); } - dbus_connection_ref(new_connection); - - /* Run connection setup function */ - DEBUG(3,("Got a connection\n")); - dst_ctx->server_connection_setup(new_connection, dst_ctx->ev); - DEBUG(3,("New connection set up.\n")); + dbus_server_unref(svw_ctx->top->server); } /* @@ -93,7 +70,8 @@ void new_connection_callback(DBusServer *server, * Set up hooks into the libevents mainloop for * D-BUS to add file descriptor-based events */ -dbus_bool_t add_server_watch(DBusWatch *watch, void *data) { +static dbus_bool_t add_server_watch(DBusWatch *watch, void *data) +{ unsigned int flags; unsigned int event_flags; struct dbus_server_toplevel_context *dt_ctx; @@ -121,11 +99,13 @@ dbus_bool_t add_server_watch(DBusWatch *watch, void *data) { if (flags & DBUS_WATCH_WRITABLE) { event_flags |= EVENT_FD_WRITE; } - svw_ctx->fde = event_add_fd(svw_ctx->top->ev, svw_ctx, svw_ctx->fd, - event_flags, dbus_server_read_write_handler, svw_ctx); + + svw_ctx->fde = event_add_fd(dt_ctx->sd_ctx->ev, svw_ctx, svw_ctx->fd, + event_flags, dbus_server_read_write_handler, + svw_ctx); /* Save the event to the watch object so it can be removed later */ - dbus_watch_set_data(svw_ctx->watch,svw_ctx->fde,NULL); + dbus_watch_set_data(svw_ctx->watch, svw_ctx->fde, NULL); return TRUE; } @@ -135,18 +115,30 @@ dbus_bool_t add_server_watch(DBusWatch *watch, void *data) { * Hook for D-BUS to toggle the enabled/disabled state of * an event in the mainloop */ -void toggle_server_watch(DBusWatch *watch, void *data) { - if (dbus_watch_get_enabled(watch)) +static void toggle_server_watch(DBusWatch *watch, void *data) +{ + if (dbus_watch_get_enabled(watch)) { add_server_watch(watch, data); - else + } else { remove_watch(watch, data); + } +} + +static void dbus_server_timeout_handler(struct event_context *ev, + struct timed_event *te, + struct timeval t, void *data) +{ + struct dbus_server_timeout_context *svt_ctx; + svt_ctx = talloc_get_type(data, struct dbus_server_timeout_context); + dbus_timeout_handle(svt_ctx->timeout); } /* * add_server_timeout * Hook for D-BUS to add time-based events to the mainloop */ -dbus_bool_t add_server_timeout(DBusTimeout *timeout, void *data) { +static dbus_bool_t add_server_timeout(DBusTimeout *timeout, void *data) +{ struct dbus_server_toplevel_context *dt_ctx; struct dbus_server_timeout_context *svt_ctx; struct timeval tv; @@ -162,11 +154,11 @@ dbus_bool_t add_server_timeout(DBusTimeout *timeout, void *data) { tv = _dbus_timeout_get_interval_tv(dbus_timeout_get_interval(timeout)); - svt_ctx->te = event_add_timed(svt_ctx->top->ev, svt_ctx, tv, - dbus_server_timeout_handler, svt_ctx); + svt_ctx->te = event_add_timed(dt_ctx->sd_ctx->ev, svt_ctx, tv, + dbus_server_timeout_handler, svt_ctx); /* Save the event to the watch object so it can be removed later */ - dbus_timeout_set_data(svt_ctx->timeout,svt_ctx->te,NULL); + dbus_timeout_set_data(svt_ctx->timeout, svt_ctx->te, NULL); return TRUE; } @@ -176,35 +168,161 @@ dbus_bool_t add_server_timeout(DBusTimeout *timeout, void *data) { * Hook for D-BUS to toggle the enabled/disabled state of a mainloop * event */ -void toggle_server_timeout(DBusTimeout *timeout, void *data) { - if (dbus_timeout_get_enabled(timeout)) +static void toggle_server_timeout(DBusTimeout *timeout, void *data) +{ + if (dbus_timeout_get_enabled(timeout)) { add_server_timeout(timeout, data); - else + } else { remove_timeout(timeout, data); + } } -/* - * dbus_server_read_write_handler - * Callback for D-BUS to handle messages on a file-descriptor +/* messsage_handler + * Receive messages and process them */ -void dbus_server_read_write_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *ptr) { - struct dbus_server_watch_context *svw_ctx; - svw_ctx = talloc_get_type(ptr,struct dbus_server_watch_context); +static DBusHandlerResult message_handler(DBusConnection *conn, + DBusMessage *message, + void *user_data) +{ + struct sssd_dbus_ctx *ctx; + const char *method; + const char *path; + const char *msg_interface; + DBusMessage *reply = NULL; + int i, ret; + + ctx = talloc_get_type(user_data, struct sssd_dbus_ctx); + + method = dbus_message_get_member(message); + path = dbus_message_get_path(message); + msg_interface = dbus_message_get_interface(message); + + if (!method || !path || !msg_interface) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + /* Validate the method interface */ + if (strcmp(msg_interface, ctx->name) != 0) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + /* Validate the D-BUS path */ + if (strcmp(path, ctx->path) == 0) { + for (i = 0; ctx->methods[i].method != NULL; i++) { + if (strcmp(method, ctx->methods[i].method) == 0) { + ret = ctx->methods[i].fn(message, ctx, &reply); + /* FIXME: check error */ + break; + } + } + /* FIXME: check if we didn't find any matching method */ + } - dbus_server_ref(svw_ctx->top->server); - if (flags & EVENT_FD_READ) { - dbus_watch_handle(svw_ctx->watch, DBUS_WATCH_READABLE); + if (reply) { + dbus_connection_send(conn, reply, NULL); + dbus_message_unref(reply); } - if (flags & EVENT_FD_WRITE) { - dbus_watch_handle(svw_ctx->watch, DBUS_WATCH_WRITABLE); + + return reply ? DBUS_HANDLER_RESULT_HANDLED : + DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +/* + * new_connection_callback + * Actions to be run upon each new client connection + * Must either perform dbus_connection_ref() on the + * new connection or else close the connection with + * dbus_connection_close() + */ +static void new_connection_callback(DBusServer *server, DBusConnection *conn, + void *data) +{ + struct dbus_server_toplevel_context *dst_ctx; + DBusObjectPathVTable *monitor_vtable; + int ret; + + dst_ctx = talloc_get_type(data,struct dbus_server_toplevel_context); + + ret = sssd_add_dbus_connection(dst_ctx->sd_ctx, conn); + if (ret != 0) { + dbus_connection_close(conn); + DEBUG(0,("Closing connection (failed setup)")); + return; } - dbus_server_ref(svw_ctx->top->server); + + dbus_connection_ref(conn); + + DEBUG(3,("Got a connection\n")); + + monitor_vtable = talloc_zero(dst_ctx, DBusObjectPathVTable); + + DEBUG (3,("Initializing D-BUS methods.\n")); + monitor_vtable->message_function = message_handler; + + dbus_connection_register_object_path(conn, dst_ctx->sd_ctx->path, + monitor_vtable, dst_ctx->sd_ctx); + + DEBUG(3,("D-BUS method initialization complete.\n")); } -void dbus_server_timeout_handler(struct event_context *ev, struct timed_event *te, - struct timeval t, void *data) { - struct dbus_server_timeout_context *svt_ctx; - svt_ctx = talloc_get_type(data, struct dbus_server_timeout_context); - dbus_timeout_handle(svt_ctx->timeout); +/* + * dbus_new_server + * Set up a D-BUS server, integrate with the event loop + * for handling file descriptor and timed events + */ +int sssd_new_dbus_server(struct sssd_dbus_ctx *ctx, const char *address) +{ + struct dbus_server_toplevel_context *dt_ctx; + DBusServer *dbus_server; + DBusError dbus_error; + dbus_bool_t dbret; + + /* Set up D-BUS server */ + dbus_error_init(&dbus_error); + dbus_server = dbus_server_listen(address, &dbus_error); + if (!dbus_server) { + DEBUG(0,("dbus_server_listen failed! (name=%s, message=%s)\n", + dbus_error.name, dbus_error.message)); + return EIO; + } + + /* TODO: remove debug */ + DEBUG(2, ("D-BUS Server listening on %s\n", + dbus_server_get_address(dbus_server))); + + dt_ctx = talloc_zero(ctx, struct dbus_server_toplevel_context); + if (!dt_ctx) { + /* FIXME: free DBusServer resources */ + return ENOMEM; + } + dt_ctx->server = dbus_server; + dt_ctx->sd_ctx = ctx; + + /* Set up D-BUS new connection handler */ + /* FIXME: set free_data_function */ + dbus_server_set_new_connection_function(dt_ctx->server, + new_connection_callback, + dt_ctx, NULL); + + /* Set up DBusWatch functions */ + dbret = dbus_server_set_watch_functions(dt_ctx->server, add_server_watch, + remove_watch, toggle_server_watch, + dt_ctx, NULL); + if (!dbret) { + DEBUG(0, ("Error setting up D-BUS server watch functions")); + /* FIXME: free DBusServer resources */ + return EIO; + } + + /* Set up DBusTimeout functions */ + dbret = dbus_server_set_timeout_functions(dt_ctx->server, + add_server_timeout, + remove_timeout, + toggle_server_timeout, + dt_ctx, NULL); + if (!dbret) { + DEBUG(0,("Error setting up D-BUS server timeout functions")); + /* FIXME: free DBusServer resources */ + return EIO; + } + + return EOK; } -- cgit