/** * g_dbus_is_address: * @string: A string. * * Checks if @string is a D-Bus address. * * This doesn't check if @string is actually supported by #GDBusServer * or #GDBusConnection - use g_dbus_is_supported_address() to do more * checks. * * Returns: %TRUE if @string is a valid D-Bus address, %FALSE otherwise. * * Since: 2.26 */ gboolean g_dbus_is_address (const gchar *string) { guint n; gchar **a; gboolean ret; ret = FALSE; g_return_val_if_fail (string != NULL, FALSE); a = g_strsplit (string, ";", 0); if (a[0] == NULL) goto out; for (n = 0; a[n] != NULL; n++) { if (!_g_dbus_address_parse_entry (a[n], NULL, NULL, NULL)) goto out; } ret = TRUE; out: g_strfreev (a); return ret; }
/** * g_dbus_is_supported_address: * @string: A string. * @error: Return location for error or %NULL. * * Like g_dbus_is_address() but also checks if the library suppors the * transports in @string and that key/value pairs for each transport * are valid. * * Returns: %TRUE if @string is a valid D-Bus address that is * supported by this library, %FALSE if @error is set. * * Since: 2.26 */ gboolean g_dbus_is_supported_address (const gchar *string, GError **error) { guint n; gchar **a; gboolean ret; ret = FALSE; g_return_val_if_fail (string != NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); a = g_strsplit (string, ";", 0); for (n = 0; a[n] != NULL; n++) { gchar *transport_name; GHashTable *key_value_pairs; gboolean supported; if (!_g_dbus_address_parse_entry (a[n], &transport_name, &key_value_pairs, error)) goto out; supported = FALSE; if (g_strcmp0 (transport_name, "unix") == 0) supported = is_valid_unix (a[n], key_value_pairs, error); else if (g_strcmp0 (transport_name, "tcp") == 0) supported = is_valid_tcp (a[n], key_value_pairs, error); else if (g_strcmp0 (transport_name, "nonce-tcp") == 0) supported = is_valid_nonce_tcp (a[n], key_value_pairs, error); else if (g_strcmp0 (a[n], "autolaunch:") == 0) supported = TRUE; g_free (transport_name); g_hash_table_unref (key_value_pairs); if (!supported) goto out; } ret = TRUE; out: g_strfreev (a); g_assert (ret || (!ret && (error == NULL || *error != NULL))); return ret; }
static GIOStream * g_dbus_address_try_connect_one (const gchar *address_entry, gchar **out_guid, GCancellable *cancellable, GError **error) { GIOStream *ret; GHashTable *key_value_pairs; gchar *transport_name; const gchar *guid; ret = NULL; transport_name = NULL; key_value_pairs = NULL; if (!_g_dbus_address_parse_entry (address_entry, &transport_name, &key_value_pairs, error)) goto out; ret = g_dbus_address_connect (address_entry, transport_name, key_value_pairs, cancellable, error); if (ret == NULL) goto out; /* TODO: validate that guid is of correct format */ guid = g_hash_table_lookup (key_value_pairs, "guid"); if (guid != NULL && out_guid != NULL) *out_guid = g_strdup (guid); out: g_free (transport_name); if (key_value_pairs != NULL) g_hash_table_unref (key_value_pairs); return ret; }
static gboolean initable_init (GInitable *initable, GCancellable *cancellable, GError **error) { GDBusServer *server = G_DBUS_SERVER (initable); gboolean ret; guint n; gchar **addr_array; GError *last_error; ret = FALSE; addr_array = NULL; last_error = NULL; if (!g_dbus_is_guid (server->guid)) { g_set_error (&last_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("The string '%s' is not a valid D-Bus GUID"), server->guid); goto out; } server->listener = G_SOCKET_LISTENER (g_threaded_socket_service_new (-1)); addr_array = g_strsplit (server->address, ";", 0); last_error = NULL; for (n = 0; addr_array != NULL && addr_array[n] != NULL; n++) { const gchar *address_entry = addr_array[n]; GHashTable *key_value_pairs; gchar *transport_name; GError *this_error; this_error = NULL; if (g_dbus_is_supported_address (address_entry, &this_error) && _g_dbus_address_parse_entry (address_entry, &transport_name, &key_value_pairs, &this_error)) { if (FALSE) { } #ifdef G_OS_UNIX else if (g_strcmp0 (transport_name, "unix") == 0) ret = try_unix (server, address_entry, key_value_pairs, &this_error); #endif else if (g_strcmp0 (transport_name, "tcp") == 0) ret = try_tcp (server, address_entry, key_value_pairs, FALSE, &this_error); else if (g_strcmp0 (transport_name, "nonce-tcp") == 0) ret = try_tcp (server, address_entry, key_value_pairs, TRUE, &this_error); else g_set_error (&this_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("Cannot listen on unsupported transport '%s'"), transport_name); g_free (transport_name); if (key_value_pairs != NULL) g_hash_table_unref (key_value_pairs); if (ret) { g_assert (this_error == NULL); goto out; } } if (this_error != NULL) { if (last_error != NULL) g_error_free (last_error); last_error = this_error; } } out: g_strfreev (addr_array); if (ret) { if (last_error != NULL) g_error_free (last_error); /* Right now we don't have any transport not using the listener... */ g_assert (server->is_using_listener); server->run_signal_handler_id = g_signal_connect (G_SOCKET_SERVICE (server->listener), "run", G_CALLBACK (on_run), server); } else { g_assert (last_error != NULL); g_propagate_error (error, last_error); } return ret; }