static void
file_replace_async_cb (GObject *source,
    GAsyncResult *res,
    gpointer user_data)
{
  EmpathyTpFile *self = user_data;
  GError *error = NULL;
  GFileOutputStream *out_stream;
  GFile *file = G_FILE (source);
  gchar *uri;
  GValue *value;

  out_stream = g_file_replace_finish (file, res, &error);

  if (error != NULL)
    {
      ft_operation_close_with_error (self, error);
      g_clear_error (&error);

      return;
    }

  self->priv->out_stream = G_OUTPUT_STREAM (out_stream);

  /* Try setting FileTranfer.URI before accepting the file */
  uri = g_file_get_uri (file);
  value = tp_g_value_slice_new_take_string (uri);

  tp_cli_dbus_properties_call_set (self->priv->channel, -1,
      TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, "URI", value,
      file_transfer_set_uri_cb, NULL, NULL, G_OBJECT (self));

  tp_g_value_slice_free (value);
}
示例#2
0
static void
tp_chat_finalize (GObject *object)
{
	EmpathyTpChatPriv *priv = GET_PRIV (object);
	guint              i;

	DEBUG ("Finalize: %p", object);

	if (priv->properties) {
		for (i = 0; i < priv->properties->len; i++) {
			TpChatProperty *property;

			property = g_ptr_array_index (priv->properties, i);
			g_free (property->name);
			if (property->value) {
				tp_g_value_slice_free (property->value);
			}
			g_slice_free (TpChatProperty, property);
		}
		g_ptr_array_free (priv->properties, TRUE);
	}

	g_queue_free (priv->messages_queue);
	g_queue_free (priv->pending_messages_queue);

	G_OBJECT_CLASS (empathy_tp_chat_parent_class)->finalize (object);
}
示例#3
0
void
conn_location_properties_getter (GObject *object,
                                 GQuark interface,
                                 GQuark name,
                                 GValue *value,
                                 gpointer getter_data)
{
  GabbleConnection *conn = GABBLE_CONNECTION (object);

  if (!tp_strdiff (g_quark_to_string (name), "LocationAccessControlTypes"))
    {
      guint access_control_type =
        TP_RICH_PRESENCE_ACCESS_CONTROL_TYPE_PUBLISH_LIST;
      GArray *access_control = g_array_sized_new (FALSE, FALSE,
          sizeof (guint), 1);

      g_array_append_val (access_control, access_control_type);
      g_value_take_boxed (value, access_control);
    }
  else if (!tp_strdiff (g_quark_to_string (name), "LocationAccessControl"))
    {
      GValueArray *access_control = g_value_array_new (2);
      GValue type = {0,};
      GValue variant = {0,};
      GValue *allocated_value;

      /* G_TYPE_UINT is the D-Bus type of TpRichPresenceAccessControlType */
      g_value_init (&type, G_TYPE_UINT);
      g_value_set_uint (&type,
          TP_RICH_PRESENCE_ACCESS_CONTROL_TYPE_PUBLISH_LIST);
      g_value_array_append (access_control, &type);
      g_value_unset (&type);

      g_value_init (&variant, G_TYPE_VALUE);
      /* For Publish_List, the variant isn't used, so we set a dummy value,
       * (guint) 0 */
      allocated_value = tp_g_value_slice_new (G_TYPE_UINT);
      g_value_set_uint (allocated_value, 0);
      g_value_set_boxed (&variant, allocated_value);
      g_value_array_append (access_control, &variant);
      g_value_unset (&variant);
      tp_g_value_slice_free (allocated_value);

      g_value_take_boxed (value, access_control);
    }
  else if (name == g_quark_from_static_string ("SupportedLocationFeatures"))
    {
      TpLocationFeatures flags = 0;

      if (conn->features & GABBLE_CONNECTION_FEATURES_PEP)
        flags |= TP_LOCATION_FEATURE_CAN_SET;

      g_value_set_uint (value, flags);
    }
  else
    {
      g_assert_not_reached ();
    }
}
static void
sig_waiting_conn_free (SigWaitingConn *sig)
{
  g_assert (sig != NULL);

  tp_g_value_slice_free (sig->param);
  g_slice_free (SigWaitingConn, sig);
}
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);
	}
}
示例#6
0
static void
debug_dialog_set_enabled (EmpathyDebugDialog *debug_dialog,
    gboolean enabled)
{
  EmpathyDebugDialogPriv *priv = GET_PRIV (debug_dialog);
  GValue *val;

  val = tp_g_value_slice_new_boolean (enabled);

  tp_cli_dbus_properties_call_set (priv->proxy, -1, EMP_IFACE_DEBUG,
      "Enabled", val, NULL, NULL, NULL, NULL);

  tp_g_value_slice_free (val);
}
static void
_offer_with_address (TpStreamTubeChannel *self,
    GHashTable *params)
{
  GValue *addressv = NULL;
  GError *error = NULL;

  addressv = tp_address_variant_from_g_socket_address (self->priv->address,
      &self->priv->socket_type, &error);
  if (error != NULL)
    {
      operation_failed (self, error);

      g_clear_error (&error);
      goto finally;
    }

  /* Connect the NewRemoteConnection signal */
  tp_cli_channel_type_stream_tube_connect_to_new_remote_connection (
      TP_CHANNEL (self), _new_remote_connection,
      NULL, NULL, G_OBJECT (self), &error);
  if (error != NULL)
    {
      operation_failed (self, error);

      g_clear_error (&error);
      goto finally;
    }

  g_assert (self->priv->parameters == NULL);
  if (params != NULL)
    self->priv->parameters = g_hash_table_ref (params);
  else
    self->priv->parameters = tp_asv_new (NULL, NULL);

  g_object_notify (G_OBJECT (self), "parameters");
  g_object_notify (G_OBJECT (self), "parameters-vardict");

  /* Call Offer */
  tp_cli_channel_type_stream_tube_call_offer (TP_CHANNEL (self), -1,
      self->priv->socket_type, addressv, self->priv->access_control,
      self->priv->parameters, _channel_offered, NULL, NULL, G_OBJECT (self));

finally:
  if (addressv != NULL)
    tp_g_value_slice_free (addressv);
}
示例#8
0
void
empathy_tp_tube_accept_stream_tube (EmpathyTpTube *tube,
  TpSocketAddressType type, EmpatyTpTubeAcceptStreamTubeCb *callback,
  gpointer user_data)
{
  EmpathyTpTubePriv *priv = GET_PRIV (tube);
  GValue *control_param;
  EmpathyTpTubeAcceptData *data;

  g_return_if_fail (EMPATHY_IS_TP_TUBE (tube));

  DEBUG ("Accepting stream tube");
  /* FIXME allow other acls */
  control_param = tp_g_value_slice_new (G_TYPE_STRING);

  data = new_empathy_tp_tube_accept_data (type, callback, user_data);

  emp_cli_channel_type_stream_tube_call_accept_stream_tube (
     TP_PROXY (priv->channel), -1, type, TP_SOCKET_ACCESS_CONTROL_LOCALHOST,
     control_param, tp_tube_accept_stream_cb, data,
     free_empathy_tp_tube_accept_data, G_OBJECT (tube));

  tp_g_value_slice_free (control_param);
}
示例#9
0
EmpathyTpTube *
empathy_tp_tube_new_stream_tube (EmpathyContact *contact,
                                 TpSocketAddressType type,
                                 const gchar *hostname,
                                 guint port,
                                 const gchar *service,
                                 GHashTable *parameters)
{
  MissionControl *mc;
  McAccount *account;
  TpConnection *connection;
  TpChannel *channel;
  gchar *object_path;
  GHashTable *params;
  GValue *address;
  GValue *control_param;
  EmpathyTpTube *tube = NULL;
  GError *error = NULL;
  GHashTable *request;
  GHashTable *channel_properties;
  GValue *value;

  g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
  g_return_val_if_fail (hostname != NULL, NULL);
  g_return_val_if_fail (service != NULL, NULL);

  mc = empathy_mission_control_dup_singleton ();
  account = empathy_contact_get_account (contact);
  connection = mission_control_get_tpconnection (mc, account, NULL);
  g_object_unref (mc);

  tp_connection_run_until_ready (connection, FALSE, NULL, NULL);

  request = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
      (GDestroyNotify) tp_g_value_slice_free);

  /* org.freedesktop.Telepathy.Channel.ChannelType */
  value = tp_g_value_slice_new (G_TYPE_STRING);
  g_value_set_string (value, EMP_IFACE_CHANNEL_TYPE_STREAM_TUBE);
  g_hash_table_insert (request, TP_IFACE_CHANNEL ".ChannelType", value);

  /* org.freedesktop.Telepathy.Channel.TargetHandleType */
  value = tp_g_value_slice_new (G_TYPE_UINT);
  g_value_set_uint (value, TP_HANDLE_TYPE_CONTACT);
  g_hash_table_insert (request, TP_IFACE_CHANNEL ".TargetHandleType", value);

  /* org.freedesktop.Telepathy.Channel.TargetHandleType */
  value = tp_g_value_slice_new (G_TYPE_UINT);
  g_value_set_uint (value, empathy_contact_get_handle (contact));
  g_hash_table_insert (request, TP_IFACE_CHANNEL ".TargetHandle", value);

  /* org.freedesktop.Telepathy.Channel.Type.StreamTube.Service */
  value = tp_g_value_slice_new (G_TYPE_STRING);
  g_value_set_string (value, service);
  g_hash_table_insert (request,
    EMP_IFACE_CHANNEL_TYPE_STREAM_TUBE  ".Service", value);

  if (!tp_cli_connection_interface_requests_run_create_channel (connection, -1,
    request, &object_path, &channel_properties, &error, NULL))
    {
      DEBUG ("Error requesting channel: %s", error->message);
      g_clear_error (&error);
      g_object_unref (connection);
      return NULL;
    }

  DEBUG ("Offering a new stream tube");

  channel = tp_channel_new_from_properties (connection, object_path,
      channel_properties, NULL);

  tp_channel_run_until_ready (channel, NULL, NULL);

  #define ADDRESS_TYPE dbus_g_type_get_struct ("GValueArray",\
      G_TYPE_STRING, G_TYPE_UINT, G_TYPE_INVALID)
  params = g_hash_table_new (g_str_hash, g_str_equal);
  address = tp_g_value_slice_new (ADDRESS_TYPE);
  g_value_take_boxed (address, dbus_g_type_specialized_construct (ADDRESS_TYPE));
  dbus_g_type_struct_set (address, 0, hostname, 1, port, G_MAXUINT);
  control_param = tp_g_value_slice_new (G_TYPE_STRING);

  if (!emp_cli_channel_type_stream_tube_run_offer_stream_tube (
        TP_PROXY(channel), -1, type, address,
        TP_SOCKET_ACCESS_CONTROL_LOCALHOST, control_param, parameters,
        &error, NULL))
    {
      DEBUG ("Couldn't offer tube: %s", error->message);
      g_clear_error (&error);
      goto OUT;
    }

  DEBUG ("Stream tube offered");

  tube = empathy_tp_tube_new (channel);

OUT:
  g_object_unref (channel);
  g_free (object_path);
  g_hash_table_destroy (request);
  g_hash_table_destroy (channel_properties);
  tp_g_value_slice_free (address);
  tp_g_value_slice_free (control_param);
  g_object_unref (connection);

  return tube;
}
示例#10
0
static void
create_channel_cb (GObject *acr,
    GAsyncResult *res,
    gpointer user_data)
{
  GSimpleAsyncResult *simple = user_data;
  CreateTubeData *data;
  GSocketListener *listener = NULL;
  gchar *dir;
  GSocket *socket = NULL;
  GSocketAddress *socket_address = NULL;
  GValue *address;
  GHashTable *parameters;
  GError *error = NULL;

  data = g_simple_async_result_get_op_res_gpointer (simple);

  if (g_cancellable_is_cancelled (data->op_cancellable))
    {
      g_object_unref (simple);
      return;
    }

  data->channel = tp_account_channel_request_create_and_handle_channel_finish (
      TP_ACCOUNT_CHANNEL_REQUEST (acr), res, NULL, &error);
   if (data->channel == NULL)
    goto OUT;

  data->invalidated_id = g_signal_connect (data->channel, "invalidated",
      G_CALLBACK (create_tube_channel_invalidated_cb), simple);

  /* We are client side, but we have to offer a socket... So we offer an unix
   * socket on which the service side can connect. We also create an IPv4 socket
   * on which the ssh client can connect. When both sockets are connected,
   * we can forward all communications between them. */

  listener = g_socket_listener_new ();

  /* Create temporary file for our unix socket */
  dir = g_build_filename (g_get_tmp_dir (), "telepathy-ssh-XXXXXX", NULL);
  dir = mkdtemp (dir);
  data->unix_path = g_build_filename (dir, "unix-socket", NULL);
  g_free (dir);

  /* Create the unix socket, and listen for connection on it */
  socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM,
      G_SOCKET_PROTOCOL_DEFAULT, &error);
  if (socket == NULL)
    goto OUT;
  socket_address = g_unix_socket_address_new (data->unix_path);
  if (!g_socket_bind (socket, socket_address, FALSE, &error))
    goto OUT; 
  if (!g_socket_listen (socket, &error))
    goto OUT;
  if (!g_socket_listener_add_socket (listener, socket, NULL, &error))
    goto OUT;

  g_socket_listener_accept_async (listener, data->op_cancellable,
    create_tube_socket_connected_cb, g_object_ref (simple));

  /* Offer the socket */
  address = tp_address_variant_from_g_socket_address (socket_address,
      TP_SOCKET_ADDRESS_TYPE_UNIX, &error);
  if (address == NULL)
    goto OUT;
  parameters = g_hash_table_new (NULL, NULL);
  data->offer_call = tp_cli_channel_type_stream_tube_call_offer (data->channel,
      -1,
      TP_SOCKET_ADDRESS_TYPE_UNIX, address,
      TP_SOCKET_ACCESS_CONTROL_LOCALHOST, parameters,
      create_tube_offer_cb, g_object_ref (simple), g_object_unref, NULL);
  tp_g_value_slice_free (address);
  g_hash_table_unref (parameters);

OUT:

  if (error != NULL)
    create_tube_complete (simple, error);

  tp_clear_object (&listener);
  tp_clear_object (&socket);
  tp_clear_object (&socket_address);
  g_clear_error (&error);
  g_object_unref (simple);
}