static void
file_read_async_cb (GObject *source,
    GAsyncResult *res,
    gpointer user_data)
{
  GValue nothing = { 0 };
  EmpathyTpFile *self = user_data;
  GFileInputStream *in_stream;
  GError *error = NULL;

  in_stream = g_file_read_finish (G_FILE (source), res, &error);

  if (error != NULL && !self->priv->is_closing)
    {
      ft_operation_close_with_error (self, error);
      g_clear_error (&error);
      return;
    }

  self->priv->in_stream = G_INPUT_STREAM (in_stream);

  /* we don't impose specific interface/port requirements even
   * if we're not using UNIX sockets.
   */
  initialize_empty_ac_variant (self->priv->socket_access_control, &nothing);

  tp_cli_channel_type_file_transfer_call_provide_file (
      self->priv->channel, -1,
      self->priv->socket_address_type, self->priv->socket_access_control,
      &nothing, ft_operation_provide_or_accept_file_cb,
      NULL, NULL, G_OBJECT (self));
}
static void
file_transfer_channel_ready (TpChannel		*channel,
                             const GError	*in_error,
			     gpointer		 user_data)
{
	GError *error = NULL;

	handle_error (in_error);

	GHashTable *map = tp_channel_borrow_immutable_properties (channel);

	const char *filename = tp_asv_get_string (map,
			TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_FILENAME);
	guint64 size = tp_asv_get_uint64 (map,
			TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_SIZE, NULL);

	g_print ("New file transfer to %s -- `%s' (%llu bytes)\n",
			tp_channel_get_identifier (channel),
			filename, size);

	/* File transfers in Telepathy work by opening a socket to the
	 * Connection Manager and streaming the file over that socket.
	 * Let's find out what manner of sockets are supported by this CM */
	GHashTable *sockets = tp_asv_get_boxed (map,
		TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_AVAILABLE_SOCKET_TYPES,
		TP_HASH_TYPE_SUPPORTED_SOCKET_MAP);

	/* let's try for IPv4 */
	if (g_hash_table_lookup (sockets,
				GINT_TO_POINTER (TP_SOCKET_ADDRESS_TYPE_IPV4)))
	{
		g_print ("ipv4 supported\n");
	}
	else if (g_hash_table_lookup (sockets,
				GINT_TO_POINTER (TP_SOCKET_ADDRESS_TYPE_UNIX)))
	{
		struct ft_state *state = g_slice_new0 (struct ft_state);
		state->sa.sun_family = AF_UNIX;

		tp_cli_channel_type_file_transfer_connect_to_file_transfer_state_changed (
				channel, file_transfer_unix_state_changed_cb,
				state, NULL, NULL, &error);
		handle_error (error);

		GValue *value = tp_g_value_slice_new_static_string ("");

		/* set up the socket for providing the file */
		tp_cli_channel_type_file_transfer_call_provide_file (
				channel, -1, TP_SOCKET_ADDRESS_TYPE_UNIX,
				TP_SOCKET_ACCESS_CONTROL_LOCALHOST,
				value, file_transfer_unix_cb,
				state, NULL, NULL);

		tp_g_value_slice_free (value);
	}
}