static DBusHandlerResult
mcd_client_registry_name_owner_filter (DBusConnection *conn,
    DBusMessage *msg,
    gpointer data)
{
  McdClientRegistry *self = MCD_CLIENT_REGISTRY (data);

  /* make sure this is the right kind of signal: */
  if (dbus_message_is_signal (msg, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
    {
      const gchar *dbus_name = NULL;
      const gchar *old_owner = NULL;
      const gchar *new_owner = NULL;
      gboolean ok = dbus_message_get_args (msg, NULL,
          DBUS_TYPE_STRING, &dbus_name,
          DBUS_TYPE_STRING, &old_owner,
          DBUS_TYPE_STRING, &new_owner,
          DBUS_TYPE_INVALID);

      /* could not unpack args -> invalid -> stop processing right here */
      if (!ok)
        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

      if (tp_str_empty (old_owner) && !tp_str_empty (new_owner))
        _mcd_client_registry_found_name (self, dbus_name, new_owner, FALSE);
    }

  /* in case somebody else is also interested */
  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
void
empathy_chat_manager_closed_chat (EmpathyChatManager *self,
    EmpathyChat *chat)
{
  EmpathyChatManagerPriv *priv = GET_PRIV (self);
  ChatData *data;
  GHashTable *chats;
  gchar *message;

  data = chat_data_new (chat);

  DEBUG ("Adding %s to closed queue: %s",
      data->room ? "room" : "contact", data->id);

  g_queue_push_tail (priv->closed_queue, data);

  g_signal_emit (self, signals[CLOSED_CHATS_CHANGED], 0,
      g_queue_get_length (priv->closed_queue));

  /* If there was a message saved from last time it was closed
   * (perhaps by accident?) save it to our hash table so it can be
   * used again when the same chat pops up. Hot. */
  message = empathy_chat_dup_text (chat);

  chats = g_hash_table_lookup (priv->messages,
      tp_proxy_get_object_path (data->account));

  /* Don't create a new hash table if we don't already have one and we
   * don't actually have a message to save. */
  if (chats == NULL && tp_str_empty (message))
    {
      g_free (message);
      return;
    }
  else if (chats == NULL && !tp_str_empty (message))
    {
      chats = g_hash_table_new_full (g_str_hash, g_str_equal,
          g_free, g_free);

      g_hash_table_insert (priv->messages,
          g_strdup (tp_proxy_get_object_path (data->account)),
          chats);
    }

  if (tp_str_empty (message))
    {
      g_hash_table_remove (chats, data->id);
      /* might be '\0' */
      g_free (message);
    }
  else
    {
      /* takes ownership of message */
      g_hash_table_insert (chats, g_strdup (data->id), message);
    }
}
static void
uoa_session_process_cb (SignonAuthSession *session,
    GHashTable *session_data,
    const GError *error,
    gpointer user_data)
{
  GSimpleAsyncResult *result = user_data;
  const gchar *password;

  if (error != NULL)
    {
      g_simple_async_result_set_from_error (result, error);
      goto out;
    }

  password = tp_asv_get_string (session_data, "Secret");
  if (tp_str_empty (password))
    {
      g_simple_async_result_set_error (result, TP_ERROR,
          TP_ERROR_DOES_NOT_EXIST, "Password not found");
      goto out;
    }

  g_simple_async_result_set_op_res_gpointer (result, g_strdup (password),
      g_free);

out:
  /* libaccounts-glib API does not guarantee the callback happens after
   * reentering mainloop */
  g_simple_async_result_complete_in_idle (result);
  g_object_unref (result);
  g_object_unref (session);
}
static gchar *
dup_network_service (EmpathyIrcNetwork *network)
{
  /* Account.Service has to be a lower case alphanumeric string which may
   * also contain '-' but not start with it. */
#define VALID G_CSET_a_2_z G_CSET_DIGITS "-"
  gchar *service, *tmp;

  service = g_strdup (empathy_irc_network_get_name (network));
  service = g_strstrip (service);

  if (tp_str_empty (service))
    {
      g_free (service);
      return NULL;
    }

  tmp = service;
  service = g_ascii_strdown (service, -1);
  g_free (tmp);

  service = g_strcanon (service, VALID, '-');

  if (service[0] == '-')
    {
      tmp = service;
      service = g_strdup (service + 1);

      g_free (tmp);
    }

  return service;
}
static gchar *
presence_hack (GStrv values)
{
  if (tp_str_empty (values[0]))
    return NULL;

  return g_markup_escape_text (values[0], -1);
}
GStrv
_client_create_exec_args (GSocket *socket,
    const gchar *contact_id,
    const gchar *username,
    gchar **ssh_opts)
{
  GPtrArray *args;
  GSocketAddress *socket_address;
  GInetAddress *inet_address;
  guint16 port;
  gchar *host;
  gchar *str;
  gchar **opt;

  /* Get the local host and port on which sshd is running */
  socket_address = g_socket_get_local_address (socket, NULL);
  inet_address = g_inet_socket_address_get_address (
      G_INET_SOCKET_ADDRESS (socket_address));
  port = g_inet_socket_address_get_port (
      G_INET_SOCKET_ADDRESS (socket_address));
  host = g_inet_address_to_string (inet_address);

  /* Create ssh client args */
  args = g_ptr_array_new_with_free_func (g_free);
  g_ptr_array_add (args, g_strdup ("ssh"));
  g_ptr_array_add (args, host);

  g_ptr_array_add (args, g_strdup ("-p"));
  str = g_strdup_printf ("%d", port);
  g_ptr_array_add (args, str);

  if (contact_id != NULL)
    {
      str = g_strdup_printf ("-oHostKeyAlias=%s", contact_id);
      g_ptr_array_add (args, str);
    }

  if (!tp_str_empty (username))
    {
      g_ptr_array_add (args, g_strdup ("-l"));
      g_ptr_array_add (args, g_strdup (username));
    }

  if (ssh_opts != NULL)
    {
      for (opt = ssh_opts; *opt != NULL; opt++)
        {
          g_ptr_array_add (args, g_strdup (*opt));
        }
    }

  g_ptr_array_add (args, NULL);

  return (gchar **) g_ptr_array_free (args, FALSE);
}
/**
 * set_password_prompt_if_needed:
 *
 * If @password is not empty, this function sets the 'password-prompt' param
 * on @ac_settings. This will ensure that Idle actually asks for the password
 * when connecting.
 *
 * Return: %TRUE if the password-prompt param has been changed
 */
static gboolean
set_password_prompt_if_needed (EmpathyAccountSettings *ac_settings,
    const gchar *password)
{
  gboolean prompt;

  prompt = !tp_str_empty (password);

  if (prompt == empathy_account_settings_get_boolean (ac_settings,
        "password-prompt"))
    return FALSE;

  empathy_account_settings_set_boolean (ac_settings, "password-prompt",
      prompt);

  return TRUE;
}
static gboolean
field_value_is_empty (TpContactInfoField *field)
{
  guint i;

  if (field->field_value == NULL)
    return TRUE;

  /* Field is empty if all its values are empty */
  for (i = 0; field->field_value[i] != NULL; i++)
    {
      if (!tp_str_empty (field->field_value[i]))
        return FALSE;
    }

  return TRUE;
}
static void
service_point_interface_check (TpConnection *tp_conn,
    const gchar **interfaces,
    const GError *error,
    gpointer data,
    GObject *connection)
{
  const gchar *interface;
  gboolean found = FALSE;
  gboolean watch = GPOINTER_TO_UINT (data);
  guint i = 0;

  if (interfaces == NULL)
    return;

  for (interface = interfaces[0];
       !found && !tp_str_empty (interface);
       interface = interfaces[++i])
    {
      if (!tp_strdiff (interface, TP_IFACE_CONNECTION_INTERFACE_SERVICE_POINT))
        found = TRUE;
    }

  if (!found)
    return;

  /* so we know if/when the service points change (eg the SIM might not be
   * accessible yet, in which case the call below won't return any entries)
   * check the flag though as we only want to do this once per connection:
   */
  if (watch)
    tp_cli_connection_interface_service_point_connect_to_service_points_changed
      (tp_conn, service_points_changed_cb, NULL, NULL, connection, NULL);

  /* fetch the current list to initialise our state */
  tp_cli_dbus_properties_call_get (tp_conn, -1,
      TP_IFACE_CONNECTION_INTERFACE_SERVICE_POINT,
      "KnownServicePoints", service_points_fetched_cb,
      NULL, NULL, connection);
}
Exemple #10
0
/**
 * empathy_ft_handler_incoming_set_destination:
 * @handler: an #EmpathyFTHandler
 * @destination: the #GFile where the transfer should be saved
 *
 * Sets the destination of the incoming handler to be @destination.
 * Note that calling this method is mandatory before starting the transfer
 * for incoming handlers.
 */
void
empathy_ft_handler_incoming_set_destination (EmpathyFTHandler *handler,
    GFile *destination)
{
  EmpathyFTHandlerPriv *priv;

  g_return_if_fail (EMPATHY_IS_FT_HANDLER (handler));
  g_return_if_fail (G_IS_FILE (destination));

  priv = handler->priv;

  g_object_set (handler, "gfile", destination, NULL);

  /* check if hash is supported. if it isn't, set use_hash to FALSE
   * anyway, so that clients won't be expecting us to checksum.
   */
  if (tp_str_empty (priv->content_hash) ||
      priv->content_hash_type == TP_FILE_HASH_TYPE_NONE)
    priv->use_hash = FALSE;
  else
    priv->use_hash = TRUE;
}
Exemple #11
0
static void
check_hash_incoming (EmpathyFTHandler *handler)
{
  HashingData *hash_data;
  EmpathyFTHandlerPriv *priv = handler->priv;

  if (!tp_str_empty (priv->content_hash))
    {
      hash_data = g_slice_new0 (HashingData);
      hash_data->total_bytes = priv->total_bytes;
      hash_data->handler = g_object_ref (handler);
      hash_data->checksum = g_checksum_new
        (tp_file_hash_to_g_checksum (priv->content_hash_type));

      g_signal_emit (handler, signals[HASHING_STARTED], 0);

      #pragma GCC diagnostic push
      #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
      g_io_scheduler_push_job (do_hash_job_incoming, hash_data, NULL,
                               G_PRIORITY_DEFAULT, priv->cancellable);
      #pragma GCC diagnostic pop
    }
}
void idle_text_send(GObject *obj, TpMessage *message, TpMessageSendingFlags flags, const gchar *recipient, IdleConnection *conn) {
    GError *error = NULL;
    const GHashTable *part;
    TpChannelTextMessageType type = TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL;
    gboolean result = TRUE;
    const gchar *content_type, *text;
    guint n_parts;
    GStrv messages;
    GStrv bodies;
    gsize msg_len;
    guint i;

#define INVALID_ARGUMENT(msg, ...) \
	G_STMT_START { \
		IDLE_DEBUG (msg , ## __VA_ARGS__); \
		g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, \
				msg , ## __VA_ARGS__); \
		goto failed; \
	} G_STMT_END

    g_return_if_fail (recipient != NULL);

    part = tp_message_peek (message, 0);

    if (tp_asv_lookup (part, "message-type") != NULL)
        type = tp_asv_get_uint32 (part, "message-type", &result);

    if (!result)
        INVALID_ARGUMENT ("message-type must be a 32-bit unsigned integer");

    if (type >= NUM_TP_CHANNEL_TEXT_MESSAGE_TYPES)
        INVALID_ARGUMENT ("invalid message type: %u", type);

    n_parts = tp_message_count_parts (message);

    if (n_parts != 2)
        INVALID_ARGUMENT ("message must contain exactly 1 part, not %u", (n_parts - 1));

    part = tp_message_peek (message, 1);
    content_type = tp_asv_get_string (part, "content-type");
    text = tp_asv_get_string (part, "content");

    if (tp_strdiff (content_type, "text/plain"))
        INVALID_ARGUMENT ("message must be text/plain");

    if (tp_str_empty (text))
        INVALID_ARGUMENT ("content must be a UTF-8 string");

    /* Okay, it's valid. Let's send it. */

    msg_len = idle_connection_get_max_message_length(conn);
    messages = idle_text_encode_and_split(type, recipient, text, msg_len, &bodies, &error);
    if (messages == NULL)
        goto failed;

    for(i = 0; messages[i] != NULL; i++) {
        g_assert(bodies[i] != NULL);
        idle_connection_send(conn, messages[i]);
    }

    g_strfreev(messages);
    g_strfreev(bodies);

    tp_message_mixin_sent (obj, message, flags, "", NULL);
    return;

failed:
    g_assert (error != NULL);
    tp_message_mixin_sent (obj, message, 0, NULL, error);
    g_error_free (error);
}
static void
process_tp_chat (EmpathyChatManager *self,
    EmpathyTpChat *tp_chat,
    TpAccount *account,
    gint64 user_action_time)
{
  EmpathyChatManagerPriv *priv = GET_PRIV (self);
  EmpathyChat *chat = NULL;
  const gchar *id;
  EmpathyChatWindow *window;

  id = empathy_tp_chat_get_id (tp_chat);
  if (!tp_str_empty (id))
    {
      chat = empathy_chat_window_find_chat (account, id,
          tp_text_channel_is_sms_channel ((TpTextChannel *) tp_chat));
    }

  if (chat != NULL)
    {
      empathy_chat_set_tp_chat (chat, tp_chat);
    }
  else
    {
      GHashTable *chats = NULL;

      chat = empathy_chat_new (tp_chat);
      /* empathy_chat_new returns a floating reference as EmpathyChat is
       * a GtkWidget. This reference will be taken by a container
       * (a GtkNotebook) when we'll call empathy_chat_window_present_chat */

      priv->num_displayed_chat++;

      DEBUG ("Chat displayed; we are now displaying %u chat",
          priv->num_displayed_chat);

      g_signal_emit (self, signals[DISPLAYED_CHATS_CHANGED], 0,
          priv->num_displayed_chat);

      /* Set the saved message in the channel if we have one. */
      chats = g_hash_table_lookup (priv->messages,
          tp_proxy_get_object_path (account));

      if (chats != NULL)
        {
          const gchar *msg = g_hash_table_lookup (chats, id);

          if (msg != NULL)
            empathy_chat_set_text (chat, msg);
        }

      g_object_weak_ref ((GObject *) chat, chat_destroyed_cb, self);
    }

  window = empathy_chat_window_present_chat (chat, user_action_time);

  if (priv->individual_mgr == NULL)
    {
      /* We want to cache it as soon it's created */
      tp_g_signal_connect_object (window, "notify::individual-manager",
        G_CALLBACK (individual_mgr_cb), self, 0);
    }

  if (empathy_tp_chat_is_invited (tp_chat, NULL))
    {
      /* We have been invited to the room. Add ourself as member as this
       * channel has been approved. */
      tp_channel_join_async (TP_CHANNEL (tp_chat), "", join_cb, self);
    }
}
static void
on_status_changed (TpYtsStatus *self,
    const gchar *contact_id,
    const gchar *capability,
    const gchar *service_name,
    const gchar *status,
    gpointer user_data,
    GObject *weak_object)
{
  GHashTable *capability_service;
  GHashTable *service_status;
  gboolean removing;

  removing = tp_str_empty (status);

  /* Dig out the capability/service dict */
  capability_service = g_hash_table_lookup (self->priv->discovered_statuses,
      contact_id);
  if (capability_service == NULL)
    {
      if (removing)
        return;
      capability_service = g_hash_table_new_full (g_str_hash, g_str_equal,
          g_free, (GDestroyNotify) g_hash_table_unref);
      g_hash_table_replace (self->priv->discovered_statuses,
          g_strdup (contact_id), capability_service);
    }

  /* Dig out the service/status dict */
  service_status = g_hash_table_lookup (capability_service, capability);
  if (service_status == NULL)
    {
      if (removing)
        return;
      service_status = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
          g_free);
      g_hash_table_replace (capability_service, g_strdup (capability),
          service_status);
    }

  if (removing)
    {
      g_hash_table_remove (service_status, service_name);
      if (g_hash_table_size (service_status) == 0)
        {
          g_hash_table_remove (capability_service, capability);
          if (g_hash_table_size (capability_service) == 0)
            {
              g_hash_table_remove (self->priv->discovered_statuses, contact_id);
            }
        }
    }
  else
    {
      g_hash_table_replace (service_status, g_strdup (service_name),
          g_strdup (status));
    }

  g_object_notify (G_OBJECT (self), "discovered-statuses");

  g_signal_emit (self, signals[STATUS_CHANGED], 0,
      contact_id, capability, service_name, status);
}