return TRUE;
}
-gboolean g_dbus_check_service(DBusConnection *connection, const char *name)
-{
- DBusMessage *message, *reply;
- const char **names;
- int i, count;
- gboolean result = FALSE;
-
- message = dbus_message_new_method_call(DBUS_SERVICE_DBUS,
- DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "ListNames");
- if (message == NULL) {
- error("Can't allocate new message");
- return FALSE;
- }
-
- reply = dbus_connection_send_with_reply_and_block(connection,
- message, -1, NULL);
-
- dbus_message_unref(message);
-
- if (reply == NULL) {
- error("Failed to execute method call");
- return FALSE;
- }
-
- if (dbus_message_get_args(reply, NULL,
- DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
- &names, &count, DBUS_TYPE_INVALID) == FALSE) {
- error("Failed to read name list");
- goto done;
- }
-
- for (i = 0; i < count; i++)
- if (g_str_equal(names[i], name) == TRUE) {
- result = TRUE;
- break;
- }
-
-done:
- dbus_message_unref(reply);
-
- return result;
-}
-
gboolean g_dbus_set_disconnect_function(DBusConnection *connection,
GDBusWatchFunction function,
void *user_data, DBusFreeFunction destroy)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
+struct service_data {
+ DBusConnection *conn;
+ const char *name;
+ GDBusWatchFunction conn_func;
+ void *user_data;
+};
+
+static void service_reply(DBusPendingCall *call, void *user_data)
+{
+ struct service_data *data = user_data;
+ DBusMessage *reply;
+ DBusError error;
+ char **names;
+ int i, count;
+
+ reply = dbus_pending_call_steal_reply(call);
+ if (reply == NULL)
+ return;
+
+ dbus_error_init(&error);
+
+ if (dbus_message_get_args(reply, &error,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &names, &count,
+ DBUS_TYPE_INVALID) == FALSE) {
+ if (dbus_error_is_set(&error) == TRUE) {
+ error("%s", error.message);
+ dbus_error_free(&error);
+ } else {
+ error("Wrong arguments for name list");
+ }
+ goto done;
+ }
+
+ for (i = 0; i < count; i++)
+ if (g_strcmp0(names[i], data->name) == 0) {
+ if (data->conn_func)
+ data->conn_func(data->conn, data->user_data);
+ break;
+ }
+
+ g_strfreev(names);
+
+done:
+ dbus_message_unref(reply);
+}
+
+static void check_service(DBusConnection *connection, const char *name,
+ GDBusWatchFunction connect, void *user_data)
+{
+ DBusMessage *message;
+ DBusPendingCall *call;
+ struct service_data *data;
+
+ data = g_try_malloc0(sizeof(*data));
+ if (data == NULL) {
+ error("Can't allocate data structure");
+ return;
+ }
+
+ data->conn = connection;
+ data->name = name;
+ data->conn_func = connect;
+ data->user_data = user_data;
+
+ message = dbus_message_new_method_call(DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "ListNames");
+ if (message == NULL) {
+ error("Can't allocate new message");
+ g_free(data);
+ return;
+ }
+
+ if (dbus_connection_send_with_reply(connection, message,
+ &call, -1) == FALSE) {
+ error("Failed to execute method call");
+ g_free(data);
+ goto done;
+ }
+
+ if (call == NULL) {
+ error("D-Bus connection not available");
+ g_free(data);
+ goto done;
+ }
+
+ dbus_pending_call_set_notify(call, service_reply, data, NULL);
+
+done:
+ dbus_message_unref(message);
+}
+
guint g_dbus_add_service_watch(DBusConnection *connection, const char *name,
GDBusWatchFunction connect,
GDBusWatchFunction disconnect,
/* The filter is already added if this is not the first callback
* registration for the name */
if (!first)
- return listener_id;
+ goto done;
if (name) {
debug("name_listener_add(%s)", name);
}
}
+done:
+ if (connect)
+ check_service(connection, name, connect, user_data);
+
return listener_id;
}