telepathygabble/src/handles.c
changeset 10 59927b2d3b75
parent 0 d0f3a028347a
--- a/telepathygabble/src/handles.c	Tue Feb 02 01:10:06 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,985 +0,0 @@
-/*
- * handles.c - mechanism to store and retrieve handles on a connection
- * Copyright (C) 2005 Collabora Ltd.
- * 
- *
- * 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
- */
-
-#include <glib.h>
-#include <dbus/dbus-glib.h>
-#include <string.h>
-
-#include "gheap.h"
-#include "handles.h"
-#include "handle-set.h"
-#include "telepathy-errors.h"
-#include "telepathy-helpers.h"
-#include "util.h"
-
-#include "config.h"
-
-#ifdef ENABLE_HANDLE_LEAK_DEBUG
-#include <stdlib.h>
-#include <stdio.h>
-#include <execinfo.h>
-
-	
-typedef struct _HandleLeakTrace HandleLeakTrace;
-
-struct _HandleLeakTrace
-{
-  char **trace;
-  int len;
-};
-
-static void
-handle_leak_trace_free (HandleLeakTrace *hltrace)
-{
-  free (hltrace->trace);
-  g_free (hltrace);
-}
-
-static void
-handle_leak_trace_free_gfunc (gpointer data, gpointer user_data)
-{
-  return handle_leak_trace_free ((HandleLeakTrace *) data);
-}
-
-#endif /* ENABLE_HANDLE_LEAK_DEBUG */
-
-/*#ifdef EMULATOR
-#include "libgabble_wsd_solution.h"
-	
-	gchar** _s_handles_list_handle_strings() { return (gchar**)((libgabble_ImpurePtr()->_s_handles_list_handle_strings)); }
-
-	#define list_handle_strings (GET_WSD_VAR_NAME(list_handle_strings,handles, s)())	
-	
-#endif*/
-	
-	
-typedef struct _GabbleHandlePriv GabbleHandlePriv;
-
-struct _GabbleHandlePriv
-{
-  guint refcount;
-  gchar *string;
-#ifdef ENABLE_HANDLE_LEAK_DEBUG
-  GSList *traces;
-#endif /* ENABLE_HANDLE_LEAK_DEBUG */
-  GData *datalist;
-};
-
-struct _GabbleHandleRepo
-{
-  GHashTable *contact_handles;
-  GHashTable *room_handles;
-  GData *list_handles;
-  GHashTable *contact_strings;
-  GHashTable *room_strings;
-  GHeap *free_contact_handles;
-  GHeap *free_room_handles;
-  guint contact_serial;
-  guint room_serial;
-  GData *client_contact_handle_sets;
-  GData *client_room_handle_sets;
-  DBusGProxy *bus_service_proxy;
-};
-
-//#ifndef EMULATOR
-static const char *list_handle_strings[GABBLE_LIST_HANDLE_DENY] =
-{
-    "publish",      /* GABBLE_LIST_HANDLE_PUBLISH */
-    "subscribe",    /* GABBLE_LIST_HANDLE_SUBSCRIBE */
-    "known",        /* GABBLE_LIST_HANDLE_KNOWN */
-    "deny"          /* GABBLE_LIST_HANDLE_DENY */
-};
-//#endif
-
-/* private functions */
-
-static GabbleHandlePriv *
-handle_priv_new ()
-{
-  GabbleHandlePriv *priv;
-
-  priv = g_new0 (GabbleHandlePriv, 1);
-
-  g_datalist_init (&(priv->datalist));
-  return priv;
-}
-
-static void
-handle_priv_free (GabbleHandlePriv *priv)
-{
-  g_assert (priv != NULL);
-
-  g_free(priv->string);
-  g_datalist_clear (&(priv->datalist));
-#ifdef ENABLE_HANDLE_LEAK_DEBUG
-  g_slist_foreach (priv->traces, handle_leak_trace_free_gfunc, NULL);
-  g_slist_free (priv->traces);
-#endif /* ENABLE_HANDLE_LEAK_DEBUG */
-  g_free (priv);
-}
-
-static GabbleHandlePriv *
-handle_priv_lookup (GabbleHandleRepo *repo,
-                    TpHandleType type,
-                    GabbleHandle handle)
-{
-  GabbleHandlePriv *priv = NULL;
-
-  g_assert (repo != NULL);
-  g_assert (gabble_handle_type_is_valid (type, NULL));
-  g_assert (handle != 0);
-
-  switch (type) {
-    case TP_HANDLE_TYPE_CONTACT:
-      priv = g_hash_table_lookup (repo->contact_handles, GINT_TO_POINTER (handle));
-      break;
-    case TP_HANDLE_TYPE_ROOM:
-      priv = g_hash_table_lookup (repo->room_handles, GINT_TO_POINTER (handle));
-      break;
-    case TP_HANDLE_TYPE_LIST:
-      priv = g_datalist_id_get_data (&repo->list_handles, handle);
-      break;
-    default:
-      g_assert_not_reached();
-    }
-
-  return priv;
-}
-
-static GabbleHandle
-gabble_handle_alloc (GabbleHandleRepo *repo, TpHandleType type)
-{
-  GabbleHandle ret = 0;
-
-  g_assert (repo != NULL);
-  g_assert (gabble_handle_type_is_valid (type, NULL));
-
-  switch (type) {
-    case TP_HANDLE_TYPE_CONTACT:
-      if (g_heap_size (repo->free_contact_handles))
-        ret = GPOINTER_TO_UINT (g_heap_extract_first (repo->free_contact_handles));
-      else
-        ret = repo->contact_serial++;
-      break;
-    case TP_HANDLE_TYPE_ROOM:
-      if (g_heap_size (repo->free_room_handles))
-        ret = GPOINTER_TO_UINT (g_heap_extract_first (repo->free_room_handles));
-      else
-        ret = repo->room_serial++;
-      break;
-    default:
-      g_assert_not_reached();
-    }
-
-  return ret;
-}
-
-static gint
-handle_compare_func (gconstpointer a, gconstpointer b)
-{
-  GabbleHandle first = GPOINTER_TO_UINT (a);
-  GabbleHandle second = GPOINTER_TO_UINT (b);
-
-  return (first == second) ? 0 : ((first < second) ? -1 : 1);
-}
-
-static void
-handle_priv_remove (GabbleHandleRepo *repo,
-                    TpHandleType type,
-                    GabbleHandle handle)
-{
-  GabbleHandlePriv *priv;
-  const gchar *string;
-
-  g_assert (gabble_handle_type_is_valid (type, NULL));
-  g_assert (handle != 0);
-  g_assert (repo != NULL);
-
-  priv = handle_priv_lookup (repo, type, handle);
-
-  g_assert (priv != NULL);
-
-  string = priv->string;
-
-  switch (type) {
-    case TP_HANDLE_TYPE_CONTACT:
-      g_hash_table_remove (repo->contact_strings, string);
-      g_hash_table_remove (repo->contact_handles, GINT_TO_POINTER (handle));
-      if (handle == repo->contact_serial-1)
-        repo->contact_serial--;
-      else
-        g_heap_add (repo->free_contact_handles, GUINT_TO_POINTER (handle));
-      break;
-    case TP_HANDLE_TYPE_ROOM:
-      g_hash_table_remove (repo->room_strings, string);
-      g_hash_table_remove (repo->room_handles, GINT_TO_POINTER (handle));
-      if (handle == repo->room_serial-1)
-        repo->room_serial--;
-      else
-        g_heap_add (repo->free_room_handles, GUINT_TO_POINTER (handle));
-      break;
-    case TP_HANDLE_TYPE_LIST:
-      g_dataset_id_remove_data (&repo->list_handles, handle);
-      break;
-    default:
-      g_assert_not_reached ();
-    }
-}
-
-static void
-handles_name_owner_changed_cb (DBusGProxy *proxy,
-                               const gchar *name,
-                               const gchar *old_owner,
-                               const gchar *new_owner,
-                               gpointer data)
-{
-  GabbleHandleRepo *repo = (GabbleHandleRepo *) data;
-
-  if (old_owner && strlen (old_owner))
-    {
-      if (!new_owner || !strlen (new_owner))
-        {
-          g_datalist_remove_data (&repo->client_contact_handle_sets, old_owner);
-          g_datalist_remove_data (&repo->client_room_handle_sets, old_owner);
-        }
-    }
-}
-
-/* public API */
-
-/**
- * gabble_handle_jid_is_valid
- *
- * Validates a jid for given handle type and returns TRUE/FALSE
- * on success/failure. In the latter case further information is
- * provided through error if set.
- */
-gboolean
-gabble_handle_jid_is_valid (TpHandleType type, const gchar *jid, GError **error)
-{
-  if (type == TP_HANDLE_TYPE_CONTACT || type == TP_HANDLE_TYPE_ROOM)
-    {
-      if (!strchr (jid, '@'))
-        {
-          g_debug ("%s: jid %s has no @", G_STRFUNC, jid);
-
-          g_set_error (error, TELEPATHY_ERRORS, InvalidArgument,
-              "jid %s has no @", jid);
-
-          return FALSE;
-        }
-
-      /* FIXME: do more extensive checking */
-    }
-  else
-    {
-      g_assert_not_reached ();
-      /* FIXME: add checking for other types here */
-    }
-
-  return TRUE;
-}
-
-gboolean
-gabble_handle_type_is_valid (TpHandleType type, GError **error)
-{
-  gboolean ret;
-
-  if (type > TP_HANDLE_TYPE_NONE && type <= TP_HANDLE_TYPE_LIST)
-    {
-      ret = TRUE;
-    }
-  else
-    {
-      g_set_error (error, TELEPATHY_ERRORS, InvalidArgument,
-          "invalid handle type %u", type);
-      ret = FALSE;
-    }
-
-  return ret;
-}
-
-
-GabbleHandleRepo *
-gabble_handle_repo_new ()
-{
-  GabbleHandleRepo *repo;
-  GabbleHandle publish, subscribe, known, deny;
-
-  repo = g_new0 (GabbleHandleRepo, 1);
-
-  repo->contact_handles = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) handle_priv_free);
-
-  repo->room_handles = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) handle_priv_free);
-
-  repo->contact_strings = g_hash_table_new (g_str_hash, g_str_equal);
-  repo->room_strings = g_hash_table_new (g_str_hash, g_str_equal);
-
-  repo->free_contact_handles = g_heap_new (handle_compare_func);
-  repo->free_room_handles = g_heap_new (handle_compare_func);
-
-  repo->contact_serial = 1;
-  repo->room_serial = 1;
-
-  g_datalist_init (&repo->list_handles);
-
-  publish = GABBLE_LIST_HANDLE_PUBLISH;
-  g_datalist_id_set_data_full (&repo->list_handles, (GQuark) publish,
-      handle_priv_new(), (GDestroyNotify) handle_priv_free);
-
-  subscribe = GABBLE_LIST_HANDLE_SUBSCRIBE;
-  g_datalist_id_set_data_full (&repo->list_handles, (GQuark) subscribe,
-      handle_priv_new(), (GDestroyNotify) handle_priv_free);
-
-  known = GABBLE_LIST_HANDLE_KNOWN;
-  g_datalist_id_set_data_full (&repo->list_handles, (GQuark) known,
-      handle_priv_new(), (GDestroyNotify) handle_priv_free);
-
-  deny = GABBLE_LIST_HANDLE_DENY;
-  g_datalist_id_set_data_full (&repo->list_handles, (GQuark) deny,
-      handle_priv_new(), (GDestroyNotify) handle_priv_free);
-
-  g_datalist_init (&repo->client_contact_handle_sets);
-  g_datalist_init (&repo->client_room_handle_sets);
-
-  repo->bus_service_proxy = dbus_g_proxy_new_for_name (tp_get_bus(),
-                                                       DBUS_SERVICE_DBUS,
-                                                       DBUS_PATH_DBUS,
-                                                       DBUS_INTERFACE_DBUS);
-
-  dbus_g_proxy_add_signal (repo->bus_service_proxy,
-                           "NameOwnerChanged",
-                           G_TYPE_STRING,
-                           G_TYPE_STRING,
-                           G_TYPE_STRING,
-                           G_TYPE_INVALID);
-  dbus_g_proxy_connect_signal (repo->bus_service_proxy,
-                               "NameOwnerChanged",
-                               G_CALLBACK (handles_name_owner_changed_cb),
-                               repo,
-                               NULL);
-
-  return repo;
-}
-
-#ifdef ENABLE_HANDLE_LEAK_DEBUG
-
-static void
-handle_leak_debug_printbt_foreach (gpointer data, gpointer user_data)
-{
-  HandleLeakTrace *hltrace = (HandleLeakTrace *) data;
-  int i;
-
-  for (i = 1; i < hltrace->len; i++)
-    {
-      g_message ("\t\t%s\n", hltrace->trace[i]);
-    }
-
-  g_message ("\n");
-}
-
-static void
-handle_leak_debug_printhandles_foreach (gpointer key, gpointer value, gpointer ignore)
-{
-  GabbleHandle handle = GPOINTER_TO_UINT (key);
-  GabbleHandlePriv *priv = (GabbleHandlePriv *) value;
-
-  g_message ("\t%5u: %s (%u refs), traces:\n", handle, priv->string, priv->refcount);
-  
-  g_slist_foreach (priv->traces, handle_leak_debug_printbt_foreach, NULL);
-}
-
-static void
-handle_leak_debug_print_report (GabbleHandleRepo *repo)
-{
-  g_assert (repo != NULL);
-
-  g_message ("The following contact handles were not freed:\n");
-  g_hash_table_foreach (repo->contact_handles, handle_leak_debug_printhandles_foreach, NULL);
-  g_message ("The following room handles were not freed:\n");
-  g_hash_table_foreach (repo->room_handles, handle_leak_debug_printhandles_foreach, NULL);
-}
-
-static HandleLeakTrace *
-handle_leak_debug_bt ()
-{
-  void *bt_addresses[16];
-  HandleLeakTrace *ret = g_new0 (HandleLeakTrace, 1);
-  
-  ret->len = backtrace (bt_addresses, 16);
-  ret->trace = backtrace_symbols (bt_addresses, ret->len);
-
-  return ret;
-}
-
-#define HANDLE_LEAK_DEBUG_DO(traces_slist) \
-  { (traces_slist) =  g_slist_append ((traces_slist), handle_leak_debug_bt ()); }
-
-#else /* !ENABLE_HANDLE_LEAK_DEBUG */
-
-#define HANDLE_LEAK_DEBUG_DO(traces_slist) {}
-
-#endif /* ENABLE_HANDLE_LEAK_DEBUG */
-
-
-void
-gabble_handle_repo_destroy (GabbleHandleRepo *repo)
-{
-  g_assert (repo != NULL);
-  g_assert (repo->contact_handles);
-  g_assert (repo->room_handles);
-  g_assert (repo->contact_strings);
-  g_assert (repo->room_strings);
-
-  g_datalist_clear (&repo->client_contact_handle_sets);
-  g_datalist_clear (&repo->client_room_handle_sets);
-
-#ifdef ENABLE_HANDLE_LEAK_DEBUG
-  handle_leak_debug_print_report (repo);
-#endif /* ENABLE_HANDLE_LEAK_DEBUG */
-
-  g_hash_table_destroy (repo->contact_handles);
-  g_hash_table_destroy (repo->room_handles);
-  g_hash_table_destroy (repo->contact_strings);
-  g_hash_table_destroy (repo->room_strings);
-  g_heap_destroy (repo->free_contact_handles);
-  g_heap_destroy (repo->free_room_handles);
-  g_datalist_clear (&repo->list_handles);
-
-  dbus_g_proxy_disconnect_signal (repo->bus_service_proxy,
-                                  "NameOwnerChanged",
-                                  G_CALLBACK (handles_name_owner_changed_cb),
-                                  repo);
-  g_object_unref (G_OBJECT (repo->bus_service_proxy));
-
-  g_free (repo);
-}
-
-
-gboolean
-gabble_handle_is_valid (GabbleHandleRepo *repo, TpHandleType type, GabbleHandle handle, GError **error)
-{
-  GArray *arr;
-  gboolean ret;
-
-  arr = g_array_new (FALSE, FALSE, sizeof (GabbleHandle));
-  g_array_insert_val (arr, 0, handle);
-
-  ret = gabble_handles_are_valid (repo, type, arr, FALSE, error);
-
-  g_array_free (arr, TRUE);
-
-  return ret;
-}
-
-gboolean
-gabble_handles_are_valid (GabbleHandleRepo *repo,
-                          TpHandleType type,
-                          const GArray *array,
-                          gboolean allow_zero,
-                          GError **error)
-{
-  guint i;
-
-  g_return_val_if_fail (repo != NULL, FALSE);
-  g_return_val_if_fail (array != NULL, FALSE);
-
-  if (!gabble_handle_type_is_valid (type, error))
-    return FALSE;
-
-  for (i = 0; i < array->len; i++)
-    {
-      GabbleHandle handle = g_array_index (array, GabbleHandle, i);
-
-      if (handle == 0)
-        {
-          if (allow_zero)
-              continue;
-
-          g_debug ("someone tried to validate handle zero");
-
-          g_set_error (error, TELEPATHY_ERRORS, InvalidArgument,
-              "invalid handle %u", handle);
-          return FALSE;
-        }
-
-      if (handle_priv_lookup (repo, type, handle) == NULL)
-        {
-          g_set_error (error, TELEPATHY_ERRORS, InvalidArgument,
-              "invalid handle %u", handle);
-          return FALSE;
-        }
-    }
-
-  return TRUE;
-}
-
-
-gboolean
-gabble_handle_ref (GabbleHandleRepo *repo,
-                   TpHandleType type,
-                   GabbleHandle handle)
-{
-  GabbleHandlePriv *priv;
-
-  if (type == TP_HANDLE_TYPE_LIST)
-    {
-      if (handle >= GABBLE_LIST_HANDLE_PUBLISH && handle <= GABBLE_LIST_HANDLE_DENY)
-        return TRUE;
-      else
-        return FALSE;
-    }
-
-  priv = handle_priv_lookup (repo, type, handle);
-
-  if (priv == NULL)
-    return FALSE;
-
-  priv->refcount++;
-
-  HANDLE_LEAK_DEBUG_DO (priv->traces);
-
-  return TRUE;
-}
-
-
-gboolean
-gabble_handle_unref (GabbleHandleRepo *repo,
-                     TpHandleType type,
-                     GabbleHandle handle)
-{
-  GabbleHandlePriv *priv;
-
-  if (type == TP_HANDLE_TYPE_LIST)
-    {
-      if (handle >= GABBLE_LIST_HANDLE_PUBLISH && handle <= GABBLE_LIST_HANDLE_DENY)
-        return TRUE;
-      else
-        return FALSE;
-    }
-
-  priv = handle_priv_lookup (repo, type, handle);
-
-  if (priv == NULL)
-    return FALSE;
-
-  HANDLE_LEAK_DEBUG_DO (priv->traces);
-
-  g_assert (priv->refcount > 0);
-
-  priv->refcount--;
-
-  if (priv->refcount == 0)
-    handle_priv_remove (repo, type, handle);
-
-  return TRUE;
-}
-
-
-const char *
-gabble_handle_inspect (GabbleHandleRepo *repo,
-                       TpHandleType type,
-                       GabbleHandle handle)
-{
-  GabbleHandlePriv *priv;
-
-  if (type == TP_HANDLE_TYPE_LIST)
-    {
-      g_assert (handle >= GABBLE_LIST_HANDLE_PUBLISH
-                  && handle <= GABBLE_LIST_HANDLE_DENY);
-      return list_handle_strings[handle-1];
-    }
-
-  priv = handle_priv_lookup (repo, type, handle);
-
-  if (priv == NULL)
-    return NULL;
-  else
-    return priv->string;
-}
-
-static GabbleHandle
-_handle_lookup_by_jid (GabbleHandleRepo *repo,
-                       const gchar *jid)
-{
-  GabbleHandle handle;
-
-  handle = GPOINTER_TO_UINT (g_hash_table_lookup (repo->contact_strings, jid));
-
-  if (0 == handle)
-    return 0;
-
-  return handle;
-}
-
-
-GabbleHandle
-gabble_handle_for_contact (GabbleHandleRepo *repo,
-                           const char *jid,
-                           gboolean with_resource)
-{
-  char *username = NULL;
-  char *server = NULL;
-  char *resource = NULL;
-  char *clean_jid = NULL;
-  GabbleHandle handle = 0;
-  GabbleHandlePriv *priv;
-
-  g_assert (repo != NULL);
-  g_assert (jid != NULL);
-  g_assert (*jid != '\0');
-
-  gabble_decode_jid (jid, &username, &server, &resource);
-
-  if (NULL == username || '\0' == *username)
-    goto OUT;
-
-  if (NULL == resource && with_resource)
-    goto OUT;
-
-  if (NULL != resource)
-    {
-      clean_jid = g_strdup_printf ("%s@%s/%s", username, server, resource);
-      handle = _handle_lookup_by_jid (repo, clean_jid);
-
-      if (0 != handle)
-        goto OUT;
-    }
-
-  if (!with_resource)
-    {
-      g_free (clean_jid);
-      clean_jid = g_strdup_printf ("%s@%s", username, server);
-      handle = _handle_lookup_by_jid (repo, clean_jid);
-
-      if (0 != handle)
-        goto OUT;
-    }
-
-  handle = gabble_handle_alloc (repo, TP_HANDLE_TYPE_CONTACT);
-  priv = handle_priv_new ();
-  priv->string = clean_jid;
-  clean_jid = NULL;
-  g_hash_table_insert (repo->contact_handles, GINT_TO_POINTER (handle), priv);
-  g_hash_table_insert (repo->contact_strings, priv->string, GUINT_TO_POINTER (handle));
-
-  HANDLE_LEAK_DEBUG_DO (priv->traces);
-
-OUT:
-
-  g_free (clean_jid);
-  g_free (username);
-  g_free (server);
-  g_free (resource);
-  return handle;
-}
-
-gboolean
-gabble_handle_for_room_exists (GabbleHandleRepo *repo,
-                               const gchar *jid,
-                               gboolean ignore_nick)
-{
-  GabbleHandle handle;
-  gchar *room, *service, *nick;
-  gchar *clean_jid;
-
-  gabble_decode_jid (jid, &room, &service, &nick);
-
-  if (!room || !service || room[0] == '\0')
-    return FALSE;
-
-  if (ignore_nick || !nick)
-    clean_jid = g_strdup_printf ("%s@%s", room, service);
-  else
-    clean_jid = g_strdup_printf ("%s@%s/%s", room, service, nick);
-
-  handle = GPOINTER_TO_UINT (g_hash_table_lookup (repo->room_strings,
-                                                  clean_jid));
-  
-  g_free (clean_jid);
-  g_free (room);
-  g_free (service);
-  g_free (nick);
-
-  if (handle == 0)
-    return FALSE;
-
-  return (handle_priv_lookup (repo, TP_HANDLE_TYPE_ROOM, handle) != NULL);
-}
-
-
-GabbleHandle
-gabble_handle_for_room (GabbleHandleRepo *repo,
-                        const gchar *jid)
-{
-  GabbleHandle handle;
-  gchar *room, *service, *clean_jid;
-
-  g_assert (repo != NULL);
-  g_assert (jid != NULL);
-  g_assert (*jid != '\0');
-
-  handle = 0;
-
-  room = service = NULL;
-  gabble_decode_jid (jid, &room, &service, NULL);
-
-  if (room && service && *room != '\0')
-    {
-      clean_jid = g_strdup_printf ("%s@%s", room, service);
-
-      handle = GPOINTER_TO_UINT (g_hash_table_lookup (repo->room_strings, clean_jid));
-
-      if (handle == 0)
-        {
-          GabbleHandlePriv *priv;
-          handle = gabble_handle_alloc (repo, TP_HANDLE_TYPE_ROOM);
-          priv = handle_priv_new ();
-          priv->string = clean_jid;
-          g_hash_table_insert (repo->room_handles, GUINT_TO_POINTER (handle), priv);
-          g_hash_table_insert (repo->room_strings, clean_jid, GUINT_TO_POINTER (handle));
-          HANDLE_LEAK_DEBUG_DO (priv->traces);
-        }
-      else
-        {
-          g_free (clean_jid);
-        }
-    }
-
-  g_free (room);
-  g_free (service);
-
-  return handle;
-}
-
-
-GabbleHandle
-gabble_handle_for_list (GabbleHandleRepo *repo,
-                        const gchar *list)
-{
-  GabbleHandle handle = 0;
-  int i;
-
-  g_assert (repo != NULL);
-  g_assert (list != NULL);
-
-  for (i = 0; i < GABBLE_LIST_HANDLE_DENY; i++)
-    {
-      if (0 == strcmp (list_handle_strings[i], list))
-        handle = (GabbleHandle) i + 1;
-    }
-
-  return handle;
-}
-
-/**
- * gabble_handle_set_qdata:
- * @repo: A #GabbleHandleRepo
- * @type: The handle type
- * @handle: A handle to set data on
- * @key_id: Key id to associate data with
- * @data: data to associate with handle
- * @destroy: A #GDestroyNotify to call to detroy the data,
- *           or NULL if not needed.
- *
- * Associates a blob of data with a given handle and a given key
- *
- * If @destroy is set, then the data is freed when the handle is freed.
- */
-
-gboolean
-gabble_handle_set_qdata (GabbleHandleRepo *repo,
-                         TpHandleType type, GabbleHandle handle,
-                         GQuark key_id, gpointer data, GDestroyNotify destroy)
-{
-  GabbleHandlePriv *priv;
-  priv = handle_priv_lookup (repo, type, handle);
-
-  if (!priv)
-    return FALSE;
-
-  g_datalist_id_set_data_full (&priv->datalist, key_id, data, destroy);
-  return TRUE;
-}
-
-/**
- * gabble_handle_get_qdata:
- * @repo: A #GabbleHandleRepo
- * @type: The handle type
- * @handle: A handle to get data from
- * @key_id: Key id of data to fetch
- *
- * Gets the data associated with a given key on a given handle
- */
-gpointer
-gabble_handle_get_qdata (GabbleHandleRepo *repo,
-                         TpHandleType type, GabbleHandle handle,
-                         GQuark key_id)
-{
-  GabbleHandlePriv *priv;
-  priv = handle_priv_lookup (repo, type, handle);
-
-  if (!priv)
-    return NULL;
-
-  return g_datalist_id_get_data(&priv->datalist, key_id);
-}
-
-/**
- * gabble_handle_client_hold:
- * @repo: a #GabbleHandleRepo
- * @client_name: D-Bus bus name of client to hold the handle for
- * @handle: the handle to hold
- * @type: type of handle to hold
- * @error: used to return a pointer to a GError detailing any error that occurred
- *
- * Marks a handle as held by a given client.
- *
- * Returns: Whether the handle was succesfully marked as held or an error occurred.
- */
-
-gboolean
-gabble_handle_client_hold (GabbleHandleRepo *repo,
-                           const gchar *client_name,
-                           GabbleHandle handle,
-                           TpHandleType type,
-                           GError **error)
-{
-  GData **handle_set_list;
-  GabbleHandleSet *handle_set;
-
-  g_assert (repo != NULL);
-
-  switch (type)
-    {
-    case TP_HANDLE_TYPE_CONTACT:
-      handle_set_list = &repo->client_contact_handle_sets;
-      break;
-    case TP_HANDLE_TYPE_ROOM:
-      handle_set_list = &repo->client_room_handle_sets;
-      break;
-    case TP_HANDLE_TYPE_LIST:
-      /* no-op */
-      return TRUE;
-    default:
-      g_critical ("%s: called with invalid handle type %u", G_STRFUNC, type);
-      g_set_error (error, TELEPATHY_ERRORS, InvalidArgument,
-          "invalid handle type %u", type);
-      return FALSE;
-    }
-
-  if (!client_name || *client_name == '\0')
-    {
-      g_critical ("%s: called with invalid client name", G_STRFUNC);
-      g_set_error (error, TELEPATHY_ERRORS, InvalidArgument,
-          "invalid client name");
-      return FALSE;
-    }
-
-  handle_set = (GabbleHandleSet*) g_datalist_get_data (handle_set_list, client_name);
-
-  if (!handle_set)
-    {
-      handle_set = handle_set_new (repo, type);
-      g_datalist_set_data_full (handle_set_list,
-                                client_name,
-                                handle_set,
-                                (GDestroyNotify) handle_set_destroy);
-    }
-
-  handle_set_add (handle_set, handle);
-
-  return TRUE;
-}
-
-/**
- * gabble_handle_client_release:
- * @repo: a #GabbleHandleRepo
- * @client_name: D-Bus bus name of client to release the handle for
- * @handle: the handle to release
- * @type: type of handle to release
- * @error: used to return a pointer to a GError detailing any error that occurred
- *
- * Unmarks a handle as held by a given client.
- *
- * Returns: Whether the handle had been marked as held by the given client and now unmarked or not.
- */
-
-gboolean
-gabble_handle_client_release (GabbleHandleRepo *repo,
-                           const gchar *client_name,
-                           GabbleHandle handle,
-                           TpHandleType type,
-                           GError **error)
-{
-  GData **handle_set_list;
-  GabbleHandleSet *handle_set;
-
-  g_assert (repo != NULL);
-
-  switch (type)
-    {
-    case TP_HANDLE_TYPE_CONTACT:
-      handle_set_list = &repo->client_contact_handle_sets;
-      break;
-    case TP_HANDLE_TYPE_ROOM:
-      handle_set_list = &repo->client_room_handle_sets;
-      break;
-    case TP_HANDLE_TYPE_LIST:
-      /* no-op */
-      return TRUE;
-    default:
-      g_critical ("%s: called with invalid handle type %u", G_STRFUNC, type);
-      g_set_error (error, TELEPATHY_ERRORS, InvalidArgument,
-          "invalid handle type %u", type);
-      return FALSE;
-    }
-
-  if (!client_name || *client_name == '\0')
-    {
-      g_critical ("%s: called with invalid client name", G_STRFUNC);
-      g_set_error (error, TELEPATHY_ERRORS, InvalidArgument,
-          "invalid client name");
-      return FALSE;
-    }
-
-  handle_set = (GabbleHandleSet*) g_datalist_get_data (handle_set_list, client_name);
-
-  if (!handle_set)
-    {
-      g_critical ("%s: no handle set found for the given client %s", G_STRFUNC, client_name);
-      g_set_error (error, TELEPATHY_ERRORS, NotAvailable,
-          "the given client %s wasn't holding any handles", client_name);
-      return FALSE;
-    }
-
-  if (!handle_set_remove (handle_set, handle))
-    {
-      g_critical ("%s: the client %s wasn't holding the handle %u", G_STRFUNC,
-          client_name, handle);
-      g_set_error (error, TELEPATHY_ERRORS, NotAvailable,
-          "the given client %s wasn't holding the handle %u", client_name,
-          handle);
-      return FALSE;
-    }
-
-  return TRUE;
-}
-