static void g_unix_socket_address_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GUnixSocketAddress *address = G_UNIX_SOCKET_ADDRESS (object); GByteArray *array; switch (prop_id) { case PROP_PATH: g_value_set_string (value, address->priv->path); break; case PROP_PATH_AS_ARRAY: array = g_byte_array_sized_new (address->priv->path_len); g_byte_array_append (array, (guint8 *)address->priv->path, address->priv->path_len); g_value_take_boxed (value, array); break; case PROP_ABSTRACT: g_value_set_boolean (value, address->priv->abstract); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } }
static char * socket_address_to_string (GSocketAddress *address) { char *res = NULL; if (G_IS_INET_SOCKET_ADDRESS (address)) { GInetAddress *inet_address; char *str; int port; inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address)); str = g_inet_address_to_string (inet_address); port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address)); res = g_strdup_printf ("%s:%d", str, port); g_free (str); } #ifdef G_OS_UNIX else if (G_IS_UNIX_SOCKET_ADDRESS (address)) { GUnixSocketAddress *uaddr = G_UNIX_SOCKET_ADDRESS (address); res = g_strdup_printf ("%s:%s", unix_socket_address_types[g_unix_socket_address_get_address_type (uaddr)], g_unix_socket_address_get_path (uaddr)); } #endif return res; }
static void g_unix_socket_address_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GUnixSocketAddress *address = G_UNIX_SOCKET_ADDRESS (object); const char *str; GByteArray *array; gsize len; switch (prop_id) { case PROP_PATH: str = g_value_get_string (value); if (str) { g_strlcpy (address->priv->path, str, sizeof (address->priv->path)); address->priv->path_len = strlen (address->priv->path); } break; case PROP_PATH_AS_ARRAY: array = g_value_get_boxed (value); if (array) { /* Clip to fit in UNIX_PATH_MAX with zero termination or first byte */ len = MIN (array->len, UNIX_PATH_MAX-1); /* Remove any trailing zeros from path_len */ while (len > 0 && array->data[len-1] == 0) len--; memcpy (address->priv->path, array->data, len); address->priv->path[len] = 0; /* Ensure null-terminated */ address->priv->path_len = len; } break; case PROP_ABSTRACT: address->priv->abstract = g_value_get_boolean (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } }
static gboolean g_unix_socket_address_to_native (GSocketAddress *address, gpointer dest, gsize destlen, GError **error) { GUnixSocketAddress *addr = G_UNIX_SOCKET_ADDRESS (address); struct sockaddr_un *sock; if (destlen < sizeof (*sock)) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE, _("Not enough space for socket address")); return FALSE; } if (addr->priv->abstract && !g_unix_socket_address_abstract_names_supported ()) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("Abstract unix domain socket addresses not supported on this system")); return FALSE; } sock = (struct sockaddr_un *) dest; sock->sun_family = AF_UNIX; memset (sock->sun_path, 0, sizeof (sock->sun_path)); if (addr->priv->abstract) { sock->sun_path[0] = 0; memcpy (sock->sun_path+1, addr->priv->path, addr->priv->path_len); } else strcpy (sock->sun_path, addr->priv->path); return TRUE; }
/* note that address_entry has already been validated => exactly one of path, tmpdir or abstract keys are set */ static gboolean try_unix (GDBusServer *server, const gchar *address_entry, GHashTable *key_value_pairs, GError **error) { gboolean ret; const gchar *path; const gchar *tmpdir; const gchar *abstract; GSocketAddress *address; ret = FALSE; address = NULL; path = g_hash_table_lookup (key_value_pairs, "path"); tmpdir = g_hash_table_lookup (key_value_pairs, "tmpdir"); abstract = g_hash_table_lookup (key_value_pairs, "abstract"); if (path != NULL) { address = g_unix_socket_address_new (path); } else if (tmpdir != NULL) { gint n; GString *s; GError *local_error; retry: s = g_string_new (tmpdir); g_string_append (s, "/dbus-"); for (n = 0; n < 8; n++) g_string_append_c (s, random_ascii ()); /* prefer abstract namespace if available */ if (g_unix_socket_address_abstract_names_supported ()) address = g_unix_socket_address_new_with_type (s->str, -1, G_UNIX_SOCKET_ADDRESS_ABSTRACT); else address = g_unix_socket_address_new (s->str); g_string_free (s, TRUE); local_error = NULL; if (!g_socket_listener_add_address (server->listener, address, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, NULL, /* source_object */ NULL, /* effective_address */ &local_error)) { if (local_error->domain == G_IO_ERROR && local_error->code == G_IO_ERROR_ADDRESS_IN_USE) { g_error_free (local_error); goto retry; } g_propagate_error (error, local_error); goto out; } ret = TRUE; goto out; } else if (abstract != NULL) { if (!g_unix_socket_address_abstract_names_supported ()) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("Abstract name space not supported")); goto out; } address = g_unix_socket_address_new_with_type (abstract, -1, G_UNIX_SOCKET_ADDRESS_ABSTRACT); } else { g_assert_not_reached (); } if (!g_socket_listener_add_address (server->listener, address, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, NULL, /* source_object */ NULL, /* effective_address */ error)) goto out; ret = TRUE; out: if (address != NULL) { /* Fill out client_address if the connection attempt worked */ if (ret) { server->is_using_listener = TRUE; switch (g_unix_socket_address_get_address_type (G_UNIX_SOCKET_ADDRESS (address))) { case G_UNIX_SOCKET_ADDRESS_ABSTRACT: server->client_address = g_strdup_printf ("unix:abstract=%s", g_unix_socket_address_get_path (G_UNIX_SOCKET_ADDRESS (address))); break; case G_UNIX_SOCKET_ADDRESS_PATH: server->client_address = g_strdup_printf ("unix:path=%s", g_unix_socket_address_get_path (G_UNIX_SOCKET_ADDRESS (address))); break; default: g_assert_not_reached (); break; } } g_object_unref (address); } return ret; }
static void tp_stream_tube_channel_dispose (GObject *obj) { TpStreamTubeChannel *self = (TpStreamTubeChannel *) obj; if (self->priv->service != NULL) { g_socket_service_stop (self->priv->service); tp_clear_object (&self->priv->service); } tp_clear_object (&self->priv->result); tp_clear_pointer (&self->priv->parameters, g_hash_table_unref); g_slist_foreach (self->priv->conn_waiting_sig, (GFunc) conn_waiting_sig_free, NULL); tp_clear_pointer (&self->priv->conn_waiting_sig, g_slist_free); g_slist_foreach (self->priv->sig_waiting_conn, (GFunc) sig_waiting_conn_free, NULL); tp_clear_pointer (&self->priv->sig_waiting_conn, g_slist_free); if (self->priv->tube_connections != NULL) { GHashTableIter iter; gpointer conn; g_hash_table_iter_init (&iter, self->priv->tube_connections); while (g_hash_table_iter_next (&iter, NULL, &conn)) { g_object_weak_unref (conn, remote_connection_destroyed_cb, self); } g_hash_table_unref (self->priv->tube_connections); self->priv->tube_connections = NULL; } if (self->priv->address != NULL) { #ifdef HAVE_GIO_UNIX /* check if we need to remove the temporary file we created */ if (G_IS_UNIX_SOCKET_ADDRESS (self->priv->address)) { const gchar *path; path = g_unix_socket_address_get_path ( G_UNIX_SOCKET_ADDRESS (self->priv->address)); g_unlink (path); } #endif /* HAVE_GIO_UNIX */ g_object_unref (self->priv->address); self->priv->address = NULL; } tp_clear_pointer (&self->priv->access_control_param, tp_g_value_slice_free); tp_clear_object (&self->priv->local_conn_waiting_id); tp_clear_object (&self->priv->client_socket); G_OBJECT_CLASS (tp_stream_tube_channel_parent_class)->dispose (obj); }