diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2014-03-31 15:38:14 +0100 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2014-04-03 15:47:14 +0100 |
commit | 6f3b018c14c11533f4e33be8669abfb8d6ad49ca (patch) | |
tree | fb4fbfeec9d498768dead7cd84e0ad2948747a96 | |
parent | d7051489e3a50e180d756c255de103aff29878f3 (diff) |
Split gnio-util.h into the Telepathy D-Bus API part, and the GIO part
The Telepathy D-Bus API part (the exact details of how we encode
addresses) should go in the -dbus library; the GIO part should go
in the main library.
Use GIOError instead of TpError in the -dbus part, so TpError won't need to
stay in the core library.
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=76855
Reviewed-by: Xavier Claessens
-rw-r--r-- | telepathy-glib/Makefile.am | 6 | ||||
-rw-r--r-- | telepathy-glib/dbus-tube-channel.c | 1 | ||||
-rw-r--r-- | telepathy-glib/file-transfer-channel.c | 1 | ||||
-rw-r--r-- | telepathy-glib/gnio-unix.c | 566 | ||||
-rw-r--r-- | telepathy-glib/gnio-unix.h | 75 | ||||
-rw-r--r-- | telepathy-glib/gnio-util.c | 520 | ||||
-rw-r--r-- | telepathy-glib/gnio-util.h | 41 | ||||
-rw-r--r-- | telepathy-glib/stream-tube-channel.c | 1 | ||||
-rw-r--r-- | telepathy-glib/telepathy-glib-dbus.h | 1 | ||||
-rw-r--r-- | telepathy-glib/telepathy-glib.h | 2 | ||||
-rw-r--r-- | telepathy-glib/versions/dbus-1.0.abi | 4 | ||||
-rw-r--r-- | telepathy-glib/versions/main-1.0.abi | 4 |
12 files changed, 662 insertions, 560 deletions
diff --git a/telepathy-glib/Makefile.am b/telepathy-glib/Makefile.am index 1465c670e..18268e201 100644 --- a/telepathy-glib/Makefile.am +++ b/telepathy-glib/Makefile.am @@ -99,7 +99,7 @@ tpginclude_HEADERS = \ errors.h \ exportable-channel.h \ file-transfer-channel.h \ - gnio-util.h \ + gnio-unix.h \ group-mixin.h \ handle.h \ handle-channel-context.h \ @@ -140,6 +140,7 @@ tpgdbusinclude_HEADERS = \ cli-channel.h \ cli-connection.h \ cli-misc.h \ + gnio-util.h \ gtypes.h \ interfaces.h \ sliced-gvalue.h \ @@ -206,6 +207,7 @@ libtelepathy_glib_dbus_internal_la_SOURCES = \ cli-channel.c \ cli-connection.c \ cli-misc.c \ + gnio-util.c \ gtypes.c \ interfaces.c \ sliced-gvalue.c \ @@ -301,7 +303,7 @@ libtelepathy_glib_main_internal_la_SOURCES = \ debug-internal.h \ exportable-channel.c \ file-transfer-channel.c \ - gnio-util.c \ + gnio-unix.c \ group-mixin.c \ handle.c \ handle-channel-context-internal.h \ diff --git a/telepathy-glib/dbus-tube-channel.c b/telepathy-glib/dbus-tube-channel.c index 471f29e57..1b7f90b05 100644 --- a/telepathy-glib/dbus-tube-channel.c +++ b/telepathy-glib/dbus-tube-channel.c @@ -89,6 +89,7 @@ #include <telepathy-glib/contact.h> #include <telepathy-glib/dbus.h> #include <telepathy-glib/enums.h> +#include <telepathy-glib/gnio-unix.h> #include <telepathy-glib/gnio-util.h> #include <telepathy-glib/gtypes.h> #include <telepathy-glib/interfaces.h> diff --git a/telepathy-glib/file-transfer-channel.c b/telepathy-glib/file-transfer-channel.c index 1e6fcd8a2..49b779b10 100644 --- a/telepathy-glib/file-transfer-channel.c +++ b/telepathy-glib/file-transfer-channel.c @@ -102,6 +102,7 @@ #include <telepathy-glib/cli-channel.h> #include <telepathy-glib/cli-misc.h> #include <telepathy-glib/dbus.h> +#include <telepathy-glib/gnio-unix.h> #include <telepathy-glib/gnio-util.h> #include <telepathy-glib/gtypes.h> #include <telepathy-glib/interfaces.h> diff --git a/telepathy-glib/gnio-unix.c b/telepathy-glib/gnio-unix.c new file mode 100644 index 000000000..084a0eb61 --- /dev/null +++ b/telepathy-glib/gnio-unix.c @@ -0,0 +1,566 @@ +/* + * gnio-unix.c - Source for telepathy-glib GNIO utility functions + * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/> + * @author Danielle Madeley <danielle.madeley@collabora.co.uk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * SECTION:gnio-util + * @title: GNIO Utilities + * @short_description: Telepathy/GNIO utility functions + * + * Utility functions for interacting between Telepathy and GNIO. + * + * Telepathy uses address variants stored in #GValue boxes for communicating + * network socket addresses over D-Bus to and from the Connection Manager + * (for instance when using the file transfer and stream tube APIs). + * + * This API provides translation between #GSocketAddress subtypes and a #GValue + * that can be used by telepathy-glib. + * #GInetSocketAddress is used for IPv4/IPv6 and #GUnixSocketAddress + * for UNIX sockets (only available on platforms with gio-unix). + */ + +#include "config.h" + +#include <gio/gio.h> + +#include <telepathy-glib/gnio-unix.h> +#include <telepathy-glib/util.h> +#include <telepathy-glib/errors.h> +#include <telepathy-glib/util-internal.h> + +#include <string.h> + +#ifdef __linux__ +/* for getsockopt() and setsockopt() */ +#include <sys/types.h> /* See NOTES */ +#include <sys/socket.h> +#include <errno.h> +#endif + +#ifdef HAVE_GIO_UNIX +#include <gio/gunixconnection.h> +#include <gio/gunixsocketaddress.h> +#include <gio/gunixcredentialsmessage.h> +#endif /* HAVE_GIO_UNIX */ + +#ifdef HAVE_GIO_UNIX +static gboolean +_tp_unix_connection_send_credentials_with_byte (GUnixConnection *connection, + guchar byte, + GCancellable *cancellable, + GError **error) +{ + /* There is not variant of g_unix_connection_send_credentials allowing us to + * choose the byte sent :( See bgo #629267 + * + * This code has been copied from glib/gunixconnection.c + * + * Copyright © 2009 Codethink Limited + */ + GCredentials *credentials; + GSocketControlMessage *scm; + GSocket *_socket; + gboolean ret; + GOutputVector vector; + + g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + ret = FALSE; + + credentials = g_credentials_new (); + + vector.buffer = &byte; + vector.size = 1; + scm = g_unix_credentials_message_new_with_credentials (credentials); + g_object_get (connection, "socket", &_socket, NULL); + if (g_socket_send_message (_socket, + NULL, /* address */ + &vector, + 1, + &scm, + 1, + G_SOCKET_MSG_NONE, + cancellable, + error) != 1) + { + g_prefix_error (error, "Error sending credentials: "); + goto out; + } + + ret = TRUE; + + out: + g_object_unref (_socket); + g_object_unref (scm); + g_object_unref (credentials); + return ret; +} +#endif + +/** + * tp_unix_connection_send_credentials_with_byte: + * @connection: a #GUnixConnection + * @byte: the byte to send with the credentials + * @cancellable: (allow-none): a #GCancellable, or %NULL + * @error: a #GError to fill + * + * A variant of g_unix_connection_send_credentials() allowing you to choose + * the byte which is send with the credentials + * + * Returns: %TRUE on success, %FALSE if error is set. + * + * Since: 0.13.2 + */ +gboolean +tp_unix_connection_send_credentials_with_byte (GSocketConnection *connection, + guchar byte, + GCancellable *cancellable, + GError **error) +{ +#ifdef HAVE_GIO_UNIX + return _tp_unix_connection_send_credentials_with_byte ( + G_UNIX_CONNECTION (connection), byte, cancellable, error); +#else + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Unix sockets not supported"); + return FALSE; +#endif +} + +static void +send_credentials_with_byte_async_thread (GSimpleAsyncResult *res, + GObject *object, + GCancellable *cancellable) +{ + guchar byte; + GError *error = NULL; + + byte = GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (res)); + + if (!tp_unix_connection_send_credentials_with_byte ( + (GSocketConnection *) object, byte, cancellable, &error)) + { + g_simple_async_result_take_error (res, error); + } +} + +/** + * tp_unix_connection_send_credentials_with_byte_async: + * @connection: A #GUnixConnection. + * @byte: the byte to send with the credentials + * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously send credentials. + * + * For more details, see tp_unix_connection_send_credentials_with_byte() which + * is the synchronous version of this call. + * + * When the operation is finished, @callback will be called. You can then call + * tp_unix_connection_send_credentials_with_byte_finish() to get the result of + * the operation. + * + * Since: 0.17.5 + **/ +void +tp_unix_connection_send_credentials_with_byte_async ( + GSocketConnection *connection, + guchar byte, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *res; + + res = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, + tp_unix_connection_send_credentials_with_byte_async); + + /* Extra casting to guint to work around GNOME#661546 for GLib < 2.32 */ + g_simple_async_result_set_op_res_gpointer (res, + GUINT_TO_POINTER ((guint) byte), NULL); + + g_simple_async_result_run_in_thread (res, + send_credentials_with_byte_async_thread, G_PRIORITY_DEFAULT, cancellable); + + g_object_unref (res); +} + +/** + * tp_unix_connection_send_credentials_with_byte_finish: + * @connection: A #GUnixConnection. + * @result: a #GAsyncResult. + * @error: a #GError, or %NULL + * + * Finishes an asynchronous send credentials operation started with + * tp_unix_connection_send_credentials_with_byte_async(). + * + * Returns: %TRUE if the operation was successful, otherwise %FALSE. + * + * Since: 0.17.5 + **/ +gboolean +tp_unix_connection_send_credentials_with_byte_finish ( + GSocketConnection *connection, + GAsyncResult *result, + GError **error) +{ + _tp_implement_finish_void (connection, + tp_unix_connection_send_credentials_with_byte_async); +} + +#ifdef HAVE_GIO_UNIX +static GCredentials * +_tp_unix_connection_receive_credentials_with_byte (GUnixConnection *connection, + guchar *byte, + GCancellable *cancellable, + GError **error) +{ + /* There is not variant of g_unix_connection_receive_credentials allowing us + * to choose the byte sent :( See bgo #629267 + * + * This code has been copied from glib/gunixconnection.c + * + * Copyright © 2009 Codethink Limited + */ + GCredentials *ret; + GSocketControlMessage **scms; + gint nscm; + GSocket *_socket; + gint n; + gssize num_bytes_read; +#ifdef __linux__ + gboolean turn_off_so_passcreds; +#endif + GInputVector vector; + guchar buffer[1]; + + g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + ret = NULL; + scms = NULL; + + g_object_get (connection, "socket", &_socket, NULL); + + /* On Linux, we need to turn on SO_PASSCRED if it isn't enabled + * already. We also need to turn it off when we're done. See + * #617483 for more discussion. + */ +#ifdef __linux__ + { + gint opt_val; + socklen_t opt_len; + + turn_off_so_passcreds = FALSE; + opt_val = 0; + opt_len = sizeof (gint); + if (getsockopt (g_socket_get_fd (_socket), + SOL_SOCKET, + SO_PASSCRED, + &opt_val, + &opt_len) != 0) + { + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errno), + "Error checking if SO_PASSCRED is enabled for socket: %s", + strerror (errno)); + goto out; + } + if (opt_len != sizeof (gint)) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Unexpected option length while checking if SO_PASSCRED is enabled for socket. " + "Expected %d bytes, got %d", + (gint) sizeof (gint), (gint) opt_len); + goto out; + } + if (opt_val == 0) + { + opt_val = 1; + if (setsockopt (g_socket_get_fd (_socket), + SOL_SOCKET, + SO_PASSCRED, + &opt_val, + sizeof opt_val) != 0) + { + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errno), + "Error enabling SO_PASSCRED: %s", + strerror (errno)); + goto out; + } + turn_off_so_passcreds = TRUE; + } + } +#endif + + vector.buffer = buffer; + vector.size = 1; + + /* ensure the type of GUnixCredentialsMessage has been registered with the type system */ + (void) (G_TYPE_UNIX_CREDENTIALS_MESSAGE); + num_bytes_read = g_socket_receive_message (_socket, + NULL, /* GSocketAddress **address */ + &vector, + 1, + &scms, + &nscm, + NULL, + cancellable, + error); + if (num_bytes_read != 1) + { + /* Handle situation where g_socket_receive_message() returns + * 0 bytes and not setting @error + */ + if (num_bytes_read == 0 && error != NULL && *error == NULL) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Expecting to read a single byte for receiving credentials but read zero bytes"); + } + goto out; + } + + if (nscm != 1) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Expecting 1 control message, got %d", + nscm); + goto out; + } + + if (!G_IS_UNIX_CREDENTIALS_MESSAGE (scms[0])) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Unexpected type of ancillary data"); + goto out; + } + + if (byte != NULL) + { + *byte = buffer[0]; + } + + ret = g_unix_credentials_message_get_credentials (G_UNIX_CREDENTIALS_MESSAGE (scms[0])); + g_object_ref (ret); + + out: + +#ifdef __linux__ + if (turn_off_so_passcreds) + { + gint opt_val; + opt_val = 0; + if (setsockopt (g_socket_get_fd (_socket), + SOL_SOCKET, + SO_PASSCRED, + &opt_val, + sizeof opt_val) != 0) + { + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errno), + "Error while disabling SO_PASSCRED: %s", + strerror (errno)); + goto out; + } + } +#endif + + if (scms != NULL) + { + for (n = 0; n < nscm; n++) + g_object_unref (scms[n]); + g_free (scms); + } + g_object_unref (_socket); + return ret; +} +#endif + +/** + * tp_unix_connection_receive_credentials_with_byte + * @connection: a #GUnixConnection + * @byte: (out): if not %NULL, used to return the byte + * @cancellable: (allow-none): a #GCancellable, or %NULL + * @error: a #GError to fill + * + * A variant of g_unix_connection_receive_credentials() allowing you to get + * the byte which has been received with the credentials. + * + * Returns: (transfer full): Received credentials on success (free with + * g_object_unref()), %NULL if error is set. + * + * Since: 0.13.2 + */ +GCredentials * +tp_unix_connection_receive_credentials_with_byte (GSocketConnection *connection, + guchar *byte, + GCancellable *cancellable, + GError **error) +{ +#ifdef HAVE_GIO_UNIX + return _tp_unix_connection_receive_credentials_with_byte ( + G_UNIX_CONNECTION (connection), byte, cancellable, error); +#else + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Unix sockets not supported"); + return FALSE; +#endif +} + +typedef struct +{ + GCredentials *creds; + guchar byte; +} ReceiveCredentialsWithByteData; + +static ReceiveCredentialsWithByteData * +receive_credentials_with_byte_data_new (GCredentials *creds, + guchar byte) +{ + ReceiveCredentialsWithByteData *data; + + data = g_slice_new0 (ReceiveCredentialsWithByteData); + data->creds = g_object_ref (creds); + data->byte = byte; + + return data; +} + +static void +receive_credentials_with_byte_data_free (ReceiveCredentialsWithByteData *data) +{ + g_object_unref (data->creds); + g_slice_free (ReceiveCredentialsWithByteData, data); +} + +static void +receive_credentials_with_byte_async_thread (GSimpleAsyncResult *res, + GObject *object, + GCancellable *cancellable) +{ + guchar byte; + GCredentials *creds; + GError *error = NULL; + + creds = tp_unix_connection_receive_credentials_with_byte ( + (GSocketConnection *) object, &byte, cancellable, &error); + if (creds == NULL) + { + g_simple_async_result_take_error (res, error); + return; + } + + g_simple_async_result_set_op_res_gpointer (res, + receive_credentials_with_byte_data_new (creds, byte), + (GDestroyNotify) receive_credentials_with_byte_data_free); + + g_object_unref (creds); +} + +/** + * tp_unix_connection_receive_credentials_with_byte_async: + * @connection: A #GUnixConnection. + * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously receive credentials. + * + * For more details, see tp_unix_connection_receive_credentials_with_byte() + * which is the synchronous version of this call. + * + * When the operation is finished, @callback will be called. You can then call + * tp_unix_connection_receive_credentials_with_byte_finish() to get the result + * of the operation. + * + * Since: 0.17.5 + **/ +void +tp_unix_connection_receive_credentials_with_byte_async ( + GSocketConnection *connection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *res; + + res = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, + tp_unix_connection_receive_credentials_with_byte_async); + + g_simple_async_result_run_in_thread (res, + receive_credentials_with_byte_async_thread, G_PRIORITY_DEFAULT, + cancellable); + + g_object_unref (res); +} + +/** + * tp_unix_connection_receive_credentials_with_byte_finish: + * @connection: A #GUnixConnection. + * @result: a #GAsyncResult. + * @byte: (out): if not %NULL, used to return the byte + * @error: a #GError, or %NULL + * + * Finishes an asynchronous receive credentials operation started with + * tp_unix_connection_receive_credentials_with_byte_async(). + * + * Returns: (transfer full): a #GCredentials, or %NULL on error. + * Free the returned object with g_object_unref(). + * + * Since: 0.17.5 + **/ +GCredentials * +tp_unix_connection_receive_credentials_with_byte_finish ( + GSocketConnection *connection, + GAsyncResult *result, + guchar *byte, + GError **error) +{ + GSimpleAsyncResult *simple = (GSimpleAsyncResult *) result; + ReceiveCredentialsWithByteData *data; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, + G_OBJECT (connection), + tp_unix_connection_receive_credentials_with_byte_async), + NULL); + + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + + data = g_simple_async_result_get_op_res_gpointer (simple); + + if (byte != NULL) + *byte = data->byte; + + return g_object_ref (data->creds); +} diff --git a/telepathy-glib/gnio-unix.h b/telepathy-glib/gnio-unix.h new file mode 100644 index 000000000..73970892e --- /dev/null +++ b/telepathy-glib/gnio-unix.h @@ -0,0 +1,75 @@ +/* + * gnio-unix.h - Headers for telepathy-glib GNIO utility functions + * + * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/> + * @author Danielle Madeley <danielle.madeley@collabora.co.uk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined (_TP_GLIB_H_INSIDE) && !defined (_TP_COMPILATION) +#error "Only <telepathy-glib/telepathy-glib.h> can be included directly." +#endif + +#include <glib-object.h> +#include <gio/gio.h> + +#include <telepathy-glib/defs.h> +#include <telepathy-glib/enums.h> + +#ifndef __TP_GNIO_UNIX_H__ +#define __TP_GNIO_UNIX_H__ + +G_BEGIN_DECLS + +gboolean tp_unix_connection_send_credentials_with_byte ( + GSocketConnection *connection, + guchar byte, + GCancellable *cancellable, + GError **error); +_TP_AVAILABLE_IN_0_18 +void tp_unix_connection_send_credentials_with_byte_async ( + GSocketConnection *connection, + guchar byte, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +_TP_AVAILABLE_IN_0_18 +gboolean tp_unix_connection_send_credentials_with_byte_finish ( + GSocketConnection *connection, + GAsyncResult *result, + GError **error); + +_TP_AVAILABLE_IN_0_18 +GCredentials * tp_unix_connection_receive_credentials_with_byte ( + GSocketConnection *connection, + guchar *byte, + GCancellable *cancellable, + GError **error); +_TP_AVAILABLE_IN_0_18 +void tp_unix_connection_receive_credentials_with_byte_async ( + GSocketConnection *connection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GCredentials *tp_unix_connection_receive_credentials_with_byte_finish ( + GSocketConnection *connection, + GAsyncResult *result, + guchar *byte, + GError **error); + +G_END_DECLS + +#endif /* __TP_GNIO_UNIX_H__ */ diff --git a/telepathy-glib/gnio-util.c b/telepathy-glib/gnio-util.c index ce4137591..d3d5f7347 100644 --- a/telepathy-glib/gnio-util.c +++ b/telepathy-glib/gnio-util.c @@ -59,9 +59,7 @@ #include <dbus/dbus-glib.h> #ifdef HAVE_GIO_UNIX -#include <gio/gunixconnection.h> #include <gio/gunixsocketaddress.h> -#include <gio/gunixcredentialsmessage.h> #endif /* HAVE_GIO_UNIX */ /** @@ -90,7 +88,7 @@ tp_g_socket_address_from_variant (TpSocketAddressType type, case TP_SOCKET_ADDRESS_TYPE_UNIX: if (!G_VALUE_HOLDS (variant, DBUS_TYPE_G_UCHAR_ARRAY)) { - g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "variant is %s not DBUS_TYPE_G_UCHAR_ARRAY", G_VALUE_TYPE_NAME (variant)); @@ -111,7 +109,7 @@ tp_g_socket_address_from_variant (TpSocketAddressType type, case TP_SOCKET_ADDRESS_TYPE_ABSTRACT_UNIX: if (!G_VALUE_HOLDS (variant, DBUS_TYPE_G_UCHAR_ARRAY)) { - g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "variant is %s not DBUS_TYPE_G_UCHAR_ARRAY", G_VALUE_TYPE_NAME (variant)); @@ -132,7 +130,7 @@ tp_g_socket_address_from_variant (TpSocketAddressType type, if (type == TP_SOCKET_ADDRESS_TYPE_IPV4 && !G_VALUE_HOLDS (variant, TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4)) { - g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "variant is %s not TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4", G_VALUE_TYPE_NAME (variant)); @@ -141,7 +139,7 @@ tp_g_socket_address_from_variant (TpSocketAddressType type, else if (type == TP_SOCKET_ADDRESS_TYPE_IPV6 && !G_VALUE_HOLDS (variant, TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV6)) { - g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "variant is %s not TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV6", G_VALUE_TYPE_NAME (variant)); @@ -172,7 +170,7 @@ tp_g_socket_address_from_variant (TpSocketAddressType type, break; default: - g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Unknown TpSocketAddressType (%i)", type); @@ -273,7 +271,7 @@ tp_address_variant_from_g_socket_address (GSocketAddress *address, break; default: - g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Unknown GSocketAddressFamily %i", g_socket_address_get_family (address)); @@ -348,509 +346,3 @@ tp_address_g_variant_from_g_socket_address (GSocketAddress *address, tp_g_value_slice_free (value); return ret; } - -#ifdef HAVE_GIO_UNIX -static gboolean -_tp_unix_connection_send_credentials_with_byte (GUnixConnection *connection, - guchar byte, - GCancellable *cancellable, - GError **error) -{ - /* There is not variant of g_unix_connection_send_credentials allowing us to - * choose the byte sent :( See bgo #629267 - * - * This code has been copied from glib/gunixconnection.c - * - * Copyright © 2009 Codethink Limited - */ - GCredentials *credentials; - GSocketControlMessage *scm; - GSocket *_socket; - gboolean ret; - GOutputVector vector; - - g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - ret = FALSE; - - credentials = g_credentials_new (); - - vector.buffer = &byte; - vector.size = 1; - scm = g_unix_credentials_message_new_with_credentials (credentials); - g_object_get (connection, "socket", &_socket, NULL); - if (g_socket_send_message (_socket, - NULL, /* address */ - &vector, - 1, - &scm, - 1, - G_SOCKET_MSG_NONE, - cancellable, - error) != 1) - { - g_prefix_error (error, "Error sending credentials: "); - goto out; - } - - ret = TRUE; - - out: - g_object_unref (_socket); - g_object_unref (scm); - g_object_unref (credentials); - return ret; -} -#endif - -/** - * tp_unix_connection_send_credentials_with_byte: - * @connection: a #GUnixConnection - * @byte: the byte to send with the credentials - * @cancellable: (allow-none): a #GCancellable, or %NULL - * @error: a #GError to fill - * - * A variant of g_unix_connection_send_credentials() allowing you to choose - * the byte which is send with the credentials - * - * Returns: %TRUE on success, %FALSE if error is set. - * - * Since: 0.13.2 - */ -gboolean -tp_unix_connection_send_credentials_with_byte (GSocketConnection *connection, - guchar byte, - GCancellable *cancellable, - GError **error) -{ -#ifdef HAVE_GIO_UNIX - return _tp_unix_connection_send_credentials_with_byte ( - G_UNIX_CONNECTION (connection), byte, cancellable, error); -#else - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "Unix sockets not supported"); - return FALSE; -#endif -} - -static void -send_credentials_with_byte_async_thread (GSimpleAsyncResult *res, - GObject *object, - GCancellable *cancellable) -{ - guchar byte; - GError *error = NULL; - - byte = GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (res)); - - if (!tp_unix_connection_send_credentials_with_byte ( - (GSocketConnection *) object, byte, cancellable, &error)) - { - g_simple_async_result_take_error (res, error); - } -} - -/** - * tp_unix_connection_send_credentials_with_byte_async: - * @connection: A #GUnixConnection. - * @byte: the byte to send with the credentials - * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore. - * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied - * @user_data: (closure): the data to pass to callback function - * - * Asynchronously send credentials. - * - * For more details, see tp_unix_connection_send_credentials_with_byte() which - * is the synchronous version of this call. - * - * When the operation is finished, @callback will be called. You can then call - * tp_unix_connection_send_credentials_with_byte_finish() to get the result of - * the operation. - * - * Since: 0.17.5 - **/ -void -tp_unix_connection_send_credentials_with_byte_async ( - GSocketConnection *connection, - guchar byte, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *res; - - res = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, - tp_unix_connection_send_credentials_with_byte_async); - - /* Extra casting to guint to work around GNOME#661546 for GLib < 2.32 */ - g_simple_async_result_set_op_res_gpointer (res, - GUINT_TO_POINTER ((guint) byte), NULL); - - g_simple_async_result_run_in_thread (res, - send_credentials_with_byte_async_thread, G_PRIORITY_DEFAULT, cancellable); - - g_object_unref (res); -} - -/** - * tp_unix_connection_send_credentials_with_byte_finish: - * @connection: A #GUnixConnection. - * @result: a #GAsyncResult. - * @error: a #GError, or %NULL - * - * Finishes an asynchronous send credentials operation started with - * tp_unix_connection_send_credentials_with_byte_async(). - * - * Returns: %TRUE if the operation was successful, otherwise %FALSE. - * - * Since: 0.17.5 - **/ -gboolean -tp_unix_connection_send_credentials_with_byte_finish ( - GSocketConnection *connection, - GAsyncResult *result, - GError **error) -{ - _tp_implement_finish_void (connection, - tp_unix_connection_send_credentials_with_byte_async); -} - -#ifdef HAVE_GIO_UNIX -static GCredentials * -_tp_unix_connection_receive_credentials_with_byte (GUnixConnection *connection, - guchar *byte, - GCancellable *cancellable, - GError **error) -{ - /* There is not variant of g_unix_connection_receive_credentials allowing us - * to choose the byte sent :( See bgo #629267 - * - * This code has been copied from glib/gunixconnection.c - * - * Copyright © 2009 Codethink Limited - */ - GCredentials *ret; - GSocketControlMessage **scms; - gint nscm; - GSocket *_socket; - gint n; - gssize num_bytes_read; -#ifdef __linux__ - gboolean turn_off_so_passcreds; -#endif - GInputVector vector; - guchar buffer[1]; - - g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - ret = NULL; - scms = NULL; - - g_object_get (connection, "socket", &_socket, NULL); - - /* On Linux, we need to turn on SO_PASSCRED if it isn't enabled - * already. We also need to turn it off when we're done. See - * #617483 for more discussion. - */ -#ifdef __linux__ - { - gint opt_val; - socklen_t opt_len; - - turn_off_so_passcreds = FALSE; - opt_val = 0; - opt_len = sizeof (gint); - if (getsockopt (g_socket_get_fd (_socket), - SOL_SOCKET, - SO_PASSCRED, - &opt_val, - &opt_len) != 0) - { - g_set_error (error, - G_IO_ERROR, - g_io_error_from_errno (errno), - "Error checking if SO_PASSCRED is enabled for socket: %s", - strerror (errno)); - goto out; - } - if (opt_len != sizeof (gint)) - { - g_set_error (error, - G_IO_ERROR, - G_IO_ERROR_FAILED, - "Unexpected option length while checking if SO_PASSCRED is enabled for socket. " - "Expected %d bytes, got %d", - (gint) sizeof (gint), (gint) opt_len); - goto out; - } - if (opt_val == 0) - { - opt_val = 1; - if (setsockopt (g_socket_get_fd (_socket), - SOL_SOCKET, - SO_PASSCRED, - &opt_val, - sizeof opt_val) != 0) - { - g_set_error (error, - G_IO_ERROR, - g_io_error_from_errno (errno), - "Error enabling SO_PASSCRED: %s", - strerror (errno)); - goto out; - } - turn_off_so_passcreds = TRUE; - } - } -#endif - - vector.buffer = buffer; - vector.size = 1; - - /* ensure the type of GUnixCredentialsMessage has been registered with the type system */ - (void) (G_TYPE_UNIX_CREDENTIALS_MESSAGE); - num_bytes_read = g_socket_receive_message (_socket, - NULL, /* GSocketAddress **address */ - &vector, - 1, - &scms, - &nscm, - NULL, - cancellable, - error); - if (num_bytes_read != 1) - { - /* Handle situation where g_socket_receive_message() returns - * 0 bytes and not setting @error - */ - if (num_bytes_read == 0 && error != NULL && *error == NULL) - { - g_set_error_literal (error, - G_IO_ERROR, - G_IO_ERROR_FAILED, - "Expecting to read a single byte for receiving credentials but read zero bytes"); - } - goto out; - } - - if (nscm != 1) - { - g_set_error (error, - G_IO_ERROR, - G_IO_ERROR_FAILED, - "Expecting 1 control message, got %d", - nscm); - goto out; - } - - if (!G_IS_UNIX_CREDENTIALS_MESSAGE (scms[0])) - { - g_set_error_literal (error, - G_IO_ERROR, - G_IO_ERROR_FAILED, - "Unexpected type of ancillary data"); - goto out; - } - - if (byte != NULL) - { - *byte = buffer[0]; - } - - ret = g_unix_credentials_message_get_credentials (G_UNIX_CREDENTIALS_MESSAGE (scms[0])); - g_object_ref (ret); - - out: - -#ifdef __linux__ - if (turn_off_so_passcreds) - { - gint opt_val; - opt_val = 0; - if (setsockopt (g_socket_get_fd (_socket), - SOL_SOCKET, - SO_PASSCRED, - &opt_val, - sizeof opt_val) != 0) - { - g_set_error (error, - G_IO_ERROR, - g_io_error_from_errno (errno), - "Error while disabling SO_PASSCRED: %s", - strerror (errno)); - goto out; - } - } -#endif - - if (scms != NULL) - { - for (n = 0; n < nscm; n++) - g_object_unref (scms[n]); - g_free (scms); - } - g_object_unref (_socket); - return ret; -} -#endif - -/** - * tp_unix_connection_receive_credentials_with_byte - * @connection: a #GUnixConnection - * @byte: (out): if not %NULL, used to return the byte - * @cancellable: (allow-none): a #GCancellable, or %NULL - * @error: a #GError to fill - * - * A variant of g_unix_connection_receive_credentials() allowing you to get - * the byte which has been received with the credentials. - * - * Returns: (transfer full): Received credentials on success (free with - * g_object_unref()), %NULL if error is set. - * - * Since: 0.13.2 - */ -GCredentials * -tp_unix_connection_receive_credentials_with_byte (GSocketConnection *connection, - guchar *byte, - GCancellable *cancellable, - GError **error) -{ -#ifdef HAVE_GIO_UNIX - return _tp_unix_connection_receive_credentials_with_byte ( - G_UNIX_CONNECTION (connection), byte, cancellable, error); -#else - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "Unix sockets not supported"); - return FALSE; -#endif -} - -typedef struct -{ - GCredentials *creds; - guchar byte; -} ReceiveCredentialsWithByteData; - -static ReceiveCredentialsWithByteData * -receive_credentials_with_byte_data_new (GCredentials *creds, - guchar byte) -{ - ReceiveCredentialsWithByteData *data; - - data = g_slice_new0 (ReceiveCredentialsWithByteData); - data->creds = g_object_ref (creds); - data->byte = byte; - - return data; -} - -static void -receive_credentials_with_byte_data_free (ReceiveCredentialsWithByteData *data) -{ - g_object_unref (data->creds); - g_slice_free (ReceiveCredentialsWithByteData, data); -} - -static void -receive_credentials_with_byte_async_thread (GSimpleAsyncResult *res, - GObject *object, - GCancellable *cancellable) -{ - guchar byte; - GCredentials *creds; - GError *error = NULL; - - creds = tp_unix_connection_receive_credentials_with_byte ( - (GSocketConnection *) object, &byte, cancellable, &error); - if (creds == NULL) - { - g_simple_async_result_take_error (res, error); - return; - } - - g_simple_async_result_set_op_res_gpointer (res, - receive_credentials_with_byte_data_new (creds, byte), - (GDestroyNotify) receive_credentials_with_byte_data_free); - - g_object_unref (creds); -} - -/** - * tp_unix_connection_receive_credentials_with_byte_async: - * @connection: A #GUnixConnection. - * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore. - * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied - * @user_data: (closure): the data to pass to callback function - * - * Asynchronously receive credentials. - * - * For more details, see tp_unix_connection_receive_credentials_with_byte() - * which is the synchronous version of this call. - * - * When the operation is finished, @callback will be called. You can then call - * tp_unix_connection_receive_credentials_with_byte_finish() to get the result - * of the operation. - * - * Since: 0.17.5 - **/ -void -tp_unix_connection_receive_credentials_with_byte_async ( - GSocketConnection *connection, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *res; - - res = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, - tp_unix_connection_receive_credentials_with_byte_async); - - g_simple_async_result_run_in_thread (res, - receive_credentials_with_byte_async_thread, G_PRIORITY_DEFAULT, - cancellable); - - g_object_unref (res); -} - -/** - * tp_unix_connection_receive_credentials_with_byte_finish: - * @connection: A #GUnixConnection. - * @result: a #GAsyncResult. - * @byte: (out): if not %NULL, used to return the byte - * @error: a #GError, or %NULL - * - * Finishes an asynchronous receive credentials operation started with - * tp_unix_connection_receive_credentials_with_byte_async(). - * - * Returns: (transfer full): a #GCredentials, or %NULL on error. - * Free the returned object with g_object_unref(). - * - * Since: 0.17.5 - **/ -GCredentials * -tp_unix_connection_receive_credentials_with_byte_finish ( - GSocketConnection *connection, - GAsyncResult *result, - guchar *byte, - GError **error) -{ - GSimpleAsyncResult *simple = (GSimpleAsyncResult *) result; - ReceiveCredentialsWithByteData *data; - - g_return_val_if_fail (g_simple_async_result_is_valid (result, - G_OBJECT (connection), - tp_unix_connection_receive_credentials_with_byte_async), - NULL); - - if (g_simple_async_result_propagate_error (simple, error)) - return NULL; - - data = g_simple_async_result_get_op_res_gpointer (simple); - - if (byte != NULL) - *byte = data->byte; - - return g_object_ref (data->creds); -} diff --git a/telepathy-glib/gnio-util.h b/telepathy-glib/gnio-util.h index 9973bc8ef..5dead020f 100644 --- a/telepathy-glib/gnio-util.h +++ b/telepathy-glib/gnio-util.h @@ -19,15 +19,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#if !defined (_TP_GLIB_H_INSIDE) && !defined (_TP_COMPILATION) +#if !defined (_TP_GLIB_DBUS_H_INSIDE) && !defined (_TP_COMPILATION) #error "Only <telepathy-glib/telepathy-glib.h> can be included directly." #endif #include <glib-object.h> #include <gio/gio.h> -#include <telepathy-glib/defs.h> -#include <telepathy-glib/enums.h> +#include <telepathy-glib/telepathy-glib.h> #ifndef __TP_GNIO_UTIL_H__ #define __TP_GNIO_UTIL_H__ @@ -50,42 +49,6 @@ GVariant *tp_address_g_variant_from_g_socket_address (GSocketAddress *address, TpSocketAddressType *type, GError **error) G_GNUC_WARN_UNUSED_RESULT; -gboolean tp_unix_connection_send_credentials_with_byte ( - GSocketConnection *connection, - guchar byte, - GCancellable *cancellable, - GError **error); -_TP_AVAILABLE_IN_0_18 -void tp_unix_connection_send_credentials_with_byte_async ( - GSocketConnection *connection, - guchar byte, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -_TP_AVAILABLE_IN_0_18 -gboolean tp_unix_connection_send_credentials_with_byte_finish ( - GSocketConnection *connection, - GAsyncResult *result, - GError **error); - -_TP_AVAILABLE_IN_0_18 -GCredentials * tp_unix_connection_receive_credentials_with_byte ( - GSocketConnection *connection, - guchar *byte, - GCancellable *cancellable, - GError **error); -_TP_AVAILABLE_IN_0_18 -void tp_unix_connection_receive_credentials_with_byte_async ( - GSocketConnection *connection, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -GCredentials *tp_unix_connection_receive_credentials_with_byte_finish ( - GSocketConnection *connection, - GAsyncResult *result, - guchar *byte, - GError **error); - G_END_DECLS #endif /* __TP_GNIO_UTIL_H__ */ diff --git a/telepathy-glib/stream-tube-channel.c b/telepathy-glib/stream-tube-channel.c index 597c7f995..cd36699b1 100644 --- a/telepathy-glib/stream-tube-channel.c +++ b/telepathy-glib/stream-tube-channel.c @@ -56,6 +56,7 @@ #include <telepathy-glib/contact.h> #include <telepathy-glib/dbus.h> #include <telepathy-glib/enums.h> +#include <telepathy-glib/gnio-unix.h> #include <telepathy-glib/gnio-util.h> #include <telepathy-glib/gtypes.h> #include <telepathy-glib/interfaces.h> diff --git a/telepathy-glib/telepathy-glib-dbus.h b/telepathy-glib/telepathy-glib-dbus.h index e67df277a..6f1ac0d05 100644 --- a/telepathy-glib/telepathy-glib-dbus.h +++ b/telepathy-glib/telepathy-glib-dbus.h @@ -31,6 +31,7 @@ #include <telepathy-glib/value-array.h> /* common */ +#include <telepathy-glib/gnio-util.h> #include <telepathy-glib/gtypes.h> #include <telepathy-glib/interfaces.h> diff --git a/telepathy-glib/telepathy-glib.h b/telepathy-glib/telepathy-glib.h index ab853639b..99b13921d 100644 --- a/telepathy-glib/telepathy-glib.h +++ b/telepathy-glib/telepathy-glib.h @@ -26,7 +26,7 @@ #include <telepathy-glib/enums.h> #include <telepathy-glib/errors.h> #include <telepathy-glib/util.h> -#include <telepathy-glib/gnio-util.h> +#include <telepathy-glib/gnio-unix.h> #include <telepathy-glib/defs.h> #include <telepathy-glib/intset.h> #include <telepathy-glib/heap.h> diff --git a/telepathy-glib/versions/dbus-1.0.abi b/telepathy-glib/versions/dbus-1.0.abi index 6f5c671f8..9f7933e1e 100644 --- a/telepathy-glib/versions/dbus-1.0.abi +++ b/telepathy-glib/versions/dbus-1.0.abi @@ -2,6 +2,8 @@ Version: TELEPATHY_GLIB_DBUS_1.0 Extends: - Release: 1.0 +tp_address_g_variant_from_g_socket_address +tp_address_variant_from_g_socket_address tp_asv_dump tp_asv_from_vardict tp_asv_get_boolean @@ -293,6 +295,8 @@ tp_cli_protocol_call_normalize_contact tp_cli_protocol_interface_addressing1_call_normalize_contact_uri tp_cli_protocol_interface_addressing1_call_normalize_vcard_address tp_dbus_specialized_value_slice_new +tp_g_socket_address_from_g_variant +tp_g_socket_address_from_variant tp_g_value_slice_dup tp_g_value_slice_free tp_g_value_slice_new diff --git a/telepathy-glib/versions/main-1.0.abi b/telepathy-glib/versions/main-1.0.abi index ec93de42b..789d34032 100644 --- a/telepathy-glib/versions/main-1.0.abi +++ b/telepathy-glib/versions/main-1.0.abi @@ -132,8 +132,6 @@ tp_add_dispatch_operation_context_accept tp_add_dispatch_operation_context_delay tp_add_dispatch_operation_context_fail tp_add_dispatch_operation_context_get_type -tp_address_g_variant_from_g_socket_address -tp_address_variant_from_g_socket_address tp_automatic_client_factory_get_type tp_automatic_client_factory_new tp_avatar_requirements_copy @@ -840,8 +838,6 @@ tp_g_hash_table_update tp_g_ptr_array_contains tp_g_ptr_array_extend tp_g_signal_connect_object -tp_g_socket_address_from_g_variant -tp_g_socket_address_from_variant tp_group_mixin_add_handle_owner tp_group_mixin_add_handle_owners tp_group_mixin_add_members |