/** * dbus_server_setup_with_g_main: * @server: the server * @context: the #GMainContext or #NULL for default * * Sets the watch and timeout functions of a #DBusServer * to integrate the server with the GLib main loop. * In most cases the context argument should be #NULL. * * If called twice for the same context, does nothing the second * time. If called once with context A and once with context B, * context B replaces context A as the context monitoring the * connection. */ void dbus_server_setup (DBusServer *server, GMainContext *context) { ConnectionSetup *old_setup; ConnectionSetup *cs; do { /* FIXME we never free the slot, so its refcount just keeps growing, * which is kind of broken. */ dbus_server_allocate_data_slot (&server_slot); if (server_slot < 0) break; if (context == NULL) context = g_main_context_default (); cs = NULL; old_setup = dbus_server_get_data (server, server_slot); if (old_setup != NULL) { if (old_setup->context == context) return; /* nothing to do */ cs = connection_setup_new_from_old (context, old_setup); /* Nuke the old setup */ dbus_server_set_data (server, server_slot, NULL, NULL); old_setup = NULL; } if (cs == NULL) cs = connection_setup_new (context, NULL); if (!dbus_server_set_data (server, server_slot, cs, (DBusFreeFunction)connection_setup_free)) break; if (!dbus_server_set_watch_functions (server, add_watch, remove_watch, watch_toggled, cs, NULL)) break; if (!dbus_server_set_timeout_functions (server, add_timeout, remove_timeout, timeout_toggled, cs, NULL)) break; return; } while (0); g_error ("Not enough memory to set up DBusServer for use with GLib"); }
static dbus_bool_t setup_server (BusContext *context, DBusServer *server, char **auth_mechanisms, DBusError *error) { BusServerData *bd; bd = dbus_new0 (BusServerData, 1); if (bd == NULL || !dbus_server_set_data (server, server_data_slot, bd, free_server_data)) { dbus_free (bd); BUS_SET_OOM (error); return FALSE; } bd->context = context; if (!dbus_server_set_auth_mechanisms (server, (const char**) auth_mechanisms)) { BUS_SET_OOM (error); return FALSE; } dbus_server_set_new_connection_function (server, new_connection_callback, context, NULL); if (!dbus_server_set_watch_functions (server, add_server_watch, remove_server_watch, toggle_server_watch, server, NULL)) { BUS_SET_OOM (error); return FALSE; } if (!dbus_server_set_timeout_functions (server, add_server_timeout, remove_server_timeout, NULL, server, NULL)) { BUS_SET_OOM (error); return FALSE; } return TRUE; }
void test_server_shutdown (DBusLoop *loop, DBusServer *server) { dbus_server_disconnect (server); if (!dbus_server_set_watch_functions (server, NULL, NULL, NULL, NULL, NULL)) _dbus_assert_not_reached ("setting watch functions to NULL failed"); if (!dbus_server_set_timeout_functions (server, NULL, NULL, NULL, NULL, NULL)) _dbus_assert_not_reached ("setting timeout functions to NULL failed"); }
dbus_bool_t test_server_setup (DBusLoop *loop, DBusServer *server) { ServerData *sd; sd = serverdata_new (loop, server); if (sd == NULL) goto nomem; if (!dbus_server_set_watch_functions (server, add_server_watch, remove_server_watch, toggle_server_watch, sd, serverdata_free)) { goto nomem; } sd = serverdata_new (loop, server); if (sd == NULL) goto nomem; if (!dbus_server_set_timeout_functions (server, add_server_timeout, remove_server_timeout, NULL, sd, serverdata_free)) { goto nomem; } return TRUE; nomem: if (sd) serverdata_free (sd); test_server_shutdown (loop, server); return FALSE; }
Integrator::Integrator( DBusServer *server, QObject *parent ) : QObject( parent ), m_server( server ) { m_connection = reinterpret_cast<DBusConnection*>( m_server ); m_timeouts.setAutoDelete( true ); dbus_server_set_watch_functions( m_server, dbusAddWatch, dbusRemoveWatch, dbusToggleWatch, this, 0 ); dbus_server_set_timeout_functions( m_server, dbusAddTimeout, dbusRemoveTimeout, dbusToggleTimeout, this, 0 ); dbus_server_set_new_connection_function( m_server, dbusNewConnection, this, 0 ); }
/* * dbus_new_server * Set up a D-BUS server, integrate with the event loop * for handling file descriptor and timed events */ int sbus_new_server(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *address, uid_t uid, gid_t gid, bool use_symlink, struct sbus_connection **_server, sbus_server_conn_init_fn init_fn, void *init_pvt_data) { struct sbus_connection *server; DBusServer *dbus_server; DBusError dbus_error; dbus_bool_t dbret; char *tmp; int ret, tmp_ret; char *filename; char *symlink_filename = NULL; const char *socket_address; struct stat stat_buf; TALLOC_CTX *tmp_ctx; *_server = NULL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; socket_address = get_socket_address(tmp_ctx, address, use_symlink); if (!socket_address) { ret = ENOMEM; goto done; } /* Set up D-BUS server */ dbus_error_init(&dbus_error); dbus_server = dbus_server_listen(socket_address, &dbus_error); if (!dbus_server) { DEBUG(SSSDBG_CRIT_FAILURE, "dbus_server_listen failed! (name=%s, message=%s)\n", dbus_error.name, dbus_error.message); if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error); ret = EIO; goto done; } filename = strchr(socket_address, '/'); if (filename == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected dbus address [%s].\n", socket_address); ret = EIO; goto done; } if (use_symlink) { symlink_filename = strchr(address, '/'); if (symlink_filename == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected dbus address [%s].\n", address); ret = EIO; goto done; } ret = create_socket_symlink(filename, symlink_filename); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not create symlink [%d]: %s\n", ret, strerror(ret)); ret = EIO; goto done; } } /* Both check_file and chmod can handle both the symlink and * the socket */ ret = check_file(filename, getuid(), getgid(), S_IFSOCK, S_IFMT, &stat_buf, true); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "check_file failed for [%s].\n", filename); ret = EIO; goto done; } if ((stat_buf.st_mode & ~S_IFMT) != (S_IRUSR|S_IWUSR)) { ret = chmod(filename, (S_IRUSR|S_IWUSR)); if (ret != EOK) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "chmod failed for [%s]: [%d][%s].\n", filename, ret, sss_strerror(ret)); ret = EIO; goto done; } } if (stat_buf.st_uid != uid || stat_buf.st_gid != gid) { ret = chown(filename, uid, gid); if (ret != EOK) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "chown failed for [%s]: [%d][%s].\n", filename, ret, sss_strerror(ret)); ret = EIO; goto done; } } tmp = dbus_server_get_address(dbus_server); DEBUG(SSSDBG_TRACE_FUNC, "D-BUS Server listening on %s\n", tmp); free(tmp); server = talloc_zero(tmp_ctx, struct sbus_connection); if (!server) { ret = ENOMEM; goto done; } server->ev = ev; server->type = SBUS_SERVER; server->dbus.server = dbus_server; server->srv_init_fn = init_fn; server->srv_init_data = init_pvt_data; talloc_set_destructor((TALLOC_CTX *)server, sbus_server_destructor); if (use_symlink) { server->symlink = talloc_strdup(server, symlink_filename); if (!server->symlink) { ret = ENOMEM; goto done; } } /* Set up D-BUS new connection handler */ dbus_server_set_new_connection_function(server->dbus.server, sbus_server_init_new_connection, server, NULL); /* Set up DBusWatch functions */ dbret = dbus_server_set_watch_functions(server->dbus.server, sbus_add_watch, sbus_remove_watch, sbus_toggle_watch, server, NULL); if (!dbret) { DEBUG(SSSDBG_CONF_SETTINGS, "Error setting up D-BUS server watch functions\n"); ret = EIO; goto done; } /* Set up DBusTimeout functions */ dbret = dbus_server_set_timeout_functions(server->dbus.server, sbus_add_timeout, sbus_remove_timeout, sbus_toggle_timeout, server, NULL); if (!dbret) { DEBUG(SSSDBG_CONF_SETTINGS, "Error setting up D-BUS server timeout functions\n"); dbus_server_set_watch_functions(server->dbus.server, NULL, NULL, NULL, NULL, NULL); ret = EIO; goto done; } *_server = talloc_steal(mem_ctx, server); ret = EOK; done: if (ret != EOK && symlink_filename) { tmp_ret = unlink(symlink_filename); /* non-fatal failure */ if (tmp_ret != EOK) { tmp_ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "Failed to remove symbolic link '%s': %d [%s]!\n", symlink_filename, tmp_ret, sss_strerror(tmp_ret)); } } talloc_free(tmp_ctx); return ret; }