Blame telepathy-account-widgets/tp-account-widgets/tpaw-irc-network-manager.c

Packit Service c6b9b0
/*
Packit Service c6b9b0
 * Copyright (C) 2007-2008 Guillaume Desmottes
Packit Service c6b9b0
 *
Packit Service c6b9b0
 * This library is free software; you can redistribute it and/or
Packit Service c6b9b0
 * modify it under the terms of the GNU Lesser General Public
Packit Service c6b9b0
 * License as published by the Free Software Foundation; either
Packit Service c6b9b0
 * version 2.1 of the License, or (at your option) any later version.
Packit Service c6b9b0
 *
Packit Service c6b9b0
 * This library is distributed in the hope that it will be useful,
Packit Service c6b9b0
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service c6b9b0
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service c6b9b0
 * Lesser General Public License for more details.
Packit Service c6b9b0
 *
Packit Service c6b9b0
 * You should have received a copy of the GNU Lesser General Public
Packit Service c6b9b0
 * License along with this library; if not, write to the Free Software
Packit Service c6b9b0
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
Packit Service c6b9b0
 *
Packit Service c6b9b0
 * Authors: Guillaume Desmottes <gdesmott@gnome.org>
Packit Service c6b9b0
 */
Packit Service c6b9b0
Packit Service c6b9b0
#include "config.h"
Packit Service c6b9b0
#include "tpaw-irc-network-manager.h"
Packit Service c6b9b0
Packit Service c6b9b0
#include <sys/stat.h>
Packit Service c6b9b0
Packit Service c6b9b0
#include "tpaw-utils.h"
Packit Service c6b9b0
Packit Service c6b9b0
#define DEBUG_FLAG TPAW_DEBUG_IRC
Packit Service c6b9b0
#include "tpaw-debug.h"
Packit Service c6b9b0
Packit Service c6b9b0
#define IRC_NETWORKS_DTD_RESOURCENAME "/org/gnome/AccountWidgets/tpaw-irc-networks.dtd"
Packit Service c6b9b0
#define IRC_NETWORKS_FILENAME "irc-networks.xml"
Packit Service c6b9b0
#define SAVE_TIMER 4
Packit Service c6b9b0
Packit Service c6b9b0
struct _TpawIrcNetworkManagerPriv {
Packit Service c6b9b0
  GHashTable *networks;
Packit Service c6b9b0
Packit Service c6b9b0
  gchar *global_file;
Packit Service c6b9b0
  gchar *user_file;
Packit Service c6b9b0
  guint last_id;
Packit Service c6b9b0
Packit Service c6b9b0
  /* Do we have to save modifications to the user file ? */
Packit Service c6b9b0
  gboolean have_to_save;
Packit Service c6b9b0
  /* Are we loading networks from XML files ? */
Packit Service c6b9b0
  gboolean loading;
Packit Service c6b9b0
  /* source id of the autosave timer */
Packit Service c6b9b0
  gint save_timer_id;
Packit Service c6b9b0
};
Packit Service c6b9b0
Packit Service c6b9b0
/* properties */
Packit Service c6b9b0
enum
Packit Service c6b9b0
{
Packit Service c6b9b0
  PROP_GLOBAL_FILE = 1,
Packit Service c6b9b0
  PROP_USER_FILE,
Packit Service c6b9b0
  LAST_PROPERTY
Packit Service c6b9b0
};
Packit Service c6b9b0
Packit Service c6b9b0
G_DEFINE_TYPE (TpawIrcNetworkManager, tpaw_irc_network_manager,
Packit Service c6b9b0
    G_TYPE_OBJECT);
Packit Service c6b9b0
Packit Service c6b9b0
static void irc_network_manager_load_servers (
Packit Service c6b9b0
    TpawIrcNetworkManager *manager);
Packit Service c6b9b0
static gboolean irc_network_manager_file_parse (
Packit Service c6b9b0
    TpawIrcNetworkManager *manager, const gchar *filename,
Packit Service c6b9b0
    gboolean user_defined);
Packit Service c6b9b0
static gboolean irc_network_manager_file_save (
Packit Service c6b9b0
    TpawIrcNetworkManager *manager);
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
tpaw_irc_network_manager_get_property (GObject *object,
Packit Service c6b9b0
                                          guint property_id,
Packit Service c6b9b0
                                          GValue *value,
Packit Service c6b9b0
                                          GParamSpec *pspec)
Packit Service c6b9b0
{
Packit Service c6b9b0
  TpawIrcNetworkManager *self = TPAW_IRC_NETWORK_MANAGER (object);
Packit Service c6b9b0
Packit Service c6b9b0
  switch (property_id)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      case PROP_GLOBAL_FILE:
Packit Service c6b9b0
        g_value_set_string (value, self->priv->global_file);
Packit Service c6b9b0
        break;
Packit Service c6b9b0
      case PROP_USER_FILE:
Packit Service c6b9b0
        g_value_set_string (value, self->priv->user_file);
Packit Service c6b9b0
        break;
Packit Service c6b9b0
      default:
Packit Service c6b9b0
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
Packit Service c6b9b0
        break;
Packit Service c6b9b0
    }
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
tpaw_irc_network_manager_set_property (GObject *object,
Packit Service c6b9b0
                                          guint property_id,
Packit Service c6b9b0
                                          const GValue *value,
Packit Service c6b9b0
                                          GParamSpec *pspec)
Packit Service c6b9b0
{
Packit Service c6b9b0
  TpawIrcNetworkManager *self = TPAW_IRC_NETWORK_MANAGER (object);
Packit Service c6b9b0
Packit Service c6b9b0
  switch (property_id)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      case PROP_GLOBAL_FILE:
Packit Service c6b9b0
        g_free (self->priv->global_file);
Packit Service c6b9b0
        self->priv->global_file = g_value_dup_string (value);
Packit Service c6b9b0
        break;
Packit Service c6b9b0
      case PROP_USER_FILE:
Packit Service c6b9b0
        g_free (self->priv->user_file);
Packit Service c6b9b0
        self->priv->user_file = g_value_dup_string (value);
Packit Service c6b9b0
        break;
Packit Service c6b9b0
      default:
Packit Service c6b9b0
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
Packit Service c6b9b0
        break;
Packit Service c6b9b0
    }
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static GObject *
Packit Service c6b9b0
tpaw_irc_network_manager_constructor (GType type,
Packit Service c6b9b0
                                         guint n_props,
Packit Service c6b9b0
                                         GObjectConstructParam *props)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GObject *obj;
Packit Service c6b9b0
  TpawIrcNetworkManager *self;
Packit Service c6b9b0
Packit Service c6b9b0
  /* Parent constructor chain */
Packit Service c6b9b0
  obj = G_OBJECT_CLASS (tpaw_irc_network_manager_parent_class)->
Packit Service c6b9b0
        constructor (type, n_props, props);
Packit Service c6b9b0
Packit Service c6b9b0
  self = TPAW_IRC_NETWORK_MANAGER (obj);
Packit Service c6b9b0
  irc_network_manager_load_servers (self);
Packit Service c6b9b0
Packit Service c6b9b0
  return obj;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
tpaw_irc_network_manager_finalize (GObject *object)
Packit Service c6b9b0
{
Packit Service c6b9b0
  TpawIrcNetworkManager *self = TPAW_IRC_NETWORK_MANAGER (object);
Packit Service c6b9b0
Packit Service c6b9b0
  if (self->priv->save_timer_id > 0)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      g_source_remove (self->priv->save_timer_id);
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  if (self->priv->have_to_save)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      irc_network_manager_file_save (self);
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  g_free (self->priv->global_file);
Packit Service c6b9b0
  g_free (self->priv->user_file);
Packit Service c6b9b0
Packit Service c6b9b0
  g_hash_table_unref (self->priv->networks);
Packit Service c6b9b0
Packit Service c6b9b0
  G_OBJECT_CLASS (tpaw_irc_network_manager_parent_class)->finalize (object);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
tpaw_irc_network_manager_init (TpawIrcNetworkManager *self)
Packit Service c6b9b0
{
Packit Service c6b9b0
  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
Packit Service c6b9b0
      TPAW_TYPE_IRC_NETWORK_MANAGER, TpawIrcNetworkManagerPriv);
Packit Service c6b9b0
Packit Service c6b9b0
  self->priv->networks = g_hash_table_new_full (g_str_hash, g_str_equal,
Packit Service c6b9b0
      (GDestroyNotify) g_free, (GDestroyNotify) g_object_unref);
Packit Service c6b9b0
Packit Service c6b9b0
  self->priv->last_id = 0;
Packit Service c6b9b0
Packit Service c6b9b0
  self->priv->have_to_save = FALSE;
Packit Service c6b9b0
  self->priv->loading = FALSE;
Packit Service c6b9b0
  self->priv->save_timer_id = 0;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
tpaw_irc_network_manager_class_init (TpawIrcNetworkManagerClass *klass)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit Service c6b9b0
  GParamSpec *param_spec;
Packit Service c6b9b0
Packit Service c6b9b0
  object_class->constructor = tpaw_irc_network_manager_constructor;
Packit Service c6b9b0
  object_class->get_property = tpaw_irc_network_manager_get_property;
Packit Service c6b9b0
  object_class->set_property = tpaw_irc_network_manager_set_property;
Packit Service c6b9b0
Packit Service c6b9b0
  g_type_class_add_private (object_class, sizeof (TpawIrcNetworkManagerPriv));
Packit Service c6b9b0
Packit Service c6b9b0
  object_class->finalize = tpaw_irc_network_manager_finalize;
Packit Service c6b9b0
Packit Service c6b9b0
  param_spec = g_param_spec_string (
Packit Service c6b9b0
      "global-file",
Packit Service c6b9b0
      "path of the global networks file",
Packit Service c6b9b0
      "The path of the system-wide filename from which we have to load"
Packit Service c6b9b0
      " the networks list",
Packit Service c6b9b0
      NULL,
Packit Service c6b9b0
      G_PARAM_CONSTRUCT_ONLY |
Packit Service c6b9b0
      G_PARAM_READWRITE |
Packit Service c6b9b0
      G_PARAM_STATIC_NAME |
Packit Service c6b9b0
      G_PARAM_STATIC_NICK |
Packit Service c6b9b0
      G_PARAM_STATIC_BLURB);
Packit Service c6b9b0
  g_object_class_install_property (object_class, PROP_GLOBAL_FILE, param_spec);
Packit Service c6b9b0
Packit Service c6b9b0
  param_spec = g_param_spec_string (
Packit Service c6b9b0
      "user-file",
Packit Service c6b9b0
      "path of the user networks file",
Packit Service c6b9b0
      "The path of user's  filename from which we have to load"
Packit Service c6b9b0
      " the networks list and to which we'll save his modifications",
Packit Service c6b9b0
      NULL,
Packit Service c6b9b0
      G_PARAM_CONSTRUCT_ONLY |
Packit Service c6b9b0
      G_PARAM_READWRITE |
Packit Service c6b9b0
      G_PARAM_STATIC_NAME |
Packit Service c6b9b0
      G_PARAM_STATIC_NICK |
Packit Service c6b9b0
      G_PARAM_STATIC_BLURB);
Packit Service c6b9b0
  g_object_class_install_property (object_class, PROP_USER_FILE, param_spec);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
/**
Packit Service c6b9b0
 * tpaw_irc_network_manager_new:
Packit Service c6b9b0
 * @global_file: the path of the global networks file, or %NULL
Packit Service c6b9b0
 * @user_file: the path of the user networks file, or %NULL
Packit Service c6b9b0
 *
Packit Service c6b9b0
 * Creates a new #TpawIrcNetworkManager
Packit Service c6b9b0
 *
Packit Service c6b9b0
 * Returns: a new #TpawIrcNetworkManager
Packit Service c6b9b0
 */
Packit Service c6b9b0
TpawIrcNetworkManager *
Packit Service c6b9b0
tpaw_irc_network_manager_new (const gchar *global_file,
Packit Service c6b9b0
                                 const gchar *user_file)
Packit Service c6b9b0
{
Packit Service c6b9b0
  TpawIrcNetworkManager *manager;
Packit Service c6b9b0
Packit Service c6b9b0
  manager = g_object_new (TPAW_TYPE_IRC_NETWORK_MANAGER,
Packit Service c6b9b0
      "global-file", global_file,
Packit Service c6b9b0
      "user-file", user_file,
Packit Service c6b9b0
      NULL);
Packit Service c6b9b0
Packit Service c6b9b0
  return manager;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static gboolean
Packit Service c6b9b0
save_timeout (TpawIrcNetworkManager *self)
Packit Service c6b9b0
{
Packit Service c6b9b0
  self->priv->save_timer_id = 0;
Packit Service c6b9b0
  irc_network_manager_file_save (self);
Packit Service c6b9b0
Packit Service c6b9b0
  return FALSE;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
reset_save_timeout (TpawIrcNetworkManager *self)
Packit Service c6b9b0
{
Packit Service c6b9b0
  if (self->priv->save_timer_id > 0)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      g_source_remove (self->priv->save_timer_id);
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  self->priv->save_timer_id = g_timeout_add_seconds (SAVE_TIMER,
Packit Service c6b9b0
      (GSourceFunc) save_timeout, self);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
network_modified (TpawIrcNetwork *network,
Packit Service c6b9b0
                  TpawIrcNetworkManager *self)
Packit Service c6b9b0
{
Packit Service c6b9b0
  network->user_defined = TRUE;
Packit Service c6b9b0
Packit Service c6b9b0
  if (!self->priv->loading)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      self->priv->have_to_save = TRUE;
Packit Service c6b9b0
      reset_save_timeout (self);
Packit Service c6b9b0
    }
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
add_network (TpawIrcNetworkManager *self,
Packit Service c6b9b0
             TpawIrcNetwork *network,
Packit Service c6b9b0
             const gchar *id)
Packit Service c6b9b0
{
Packit Service c6b9b0
  g_hash_table_insert (self->priv->networks, g_strdup (id),
Packit Service c6b9b0
      g_object_ref (network));
Packit Service c6b9b0
Packit Service c6b9b0
  g_signal_connect (network, "modified", G_CALLBACK (network_modified), self);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
/**
Packit Service c6b9b0
 * tpaw_irc_network_manager_add:
Packit Service c6b9b0
 * @manager: an #TpawIrcNetworkManager
Packit Service c6b9b0
 * @network: the #TpawIrcNetwork to add
Packit Service c6b9b0
 *
Packit Service c6b9b0
 * Add an #TpawIrcNetwork to the given #TpawIrcNetworkManager.
Packit Service c6b9b0
 *
Packit Service c6b9b0
 */
Packit Service c6b9b0
void
Packit Service c6b9b0
tpaw_irc_network_manager_add (TpawIrcNetworkManager *self,
Packit Service c6b9b0
                                 TpawIrcNetwork *network)
Packit Service c6b9b0
{
Packit Service c6b9b0
  gchar *id = NULL;
Packit Service c6b9b0
Packit Service c6b9b0
  g_return_if_fail (TPAW_IS_IRC_NETWORK_MANAGER (self));
Packit Service c6b9b0
  g_return_if_fail (TPAW_IS_IRC_NETWORK (network));
Packit Service c6b9b0
Packit Service c6b9b0
  /* generate an id for this network */
Packit Service c6b9b0
  do
Packit Service c6b9b0
    {
Packit Service c6b9b0
      g_free (id);
Packit Service c6b9b0
      id = g_strdup_printf ("id%u", ++self->priv->last_id);
Packit Service c6b9b0
    } while (g_hash_table_lookup (self->priv->networks, id) != NULL &&
Packit Service c6b9b0
        self->priv->last_id < G_MAXUINT);
Packit Service c6b9b0
Packit Service c6b9b0
  if (self->priv->last_id == G_MAXUINT)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      DEBUG ("Can't add network: too many networks using a similar ID");
Packit Service c6b9b0
      return;
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  DEBUG ("add server with \"%s\" as ID", id);
Packit Service c6b9b0
Packit Service c6b9b0
  network->user_defined = TRUE;
Packit Service c6b9b0
  add_network (self, network, id);
Packit Service c6b9b0
Packit Service c6b9b0
  self->priv->have_to_save = TRUE;
Packit Service c6b9b0
  reset_save_timeout (self);
Packit Service c6b9b0
Packit Service c6b9b0
  g_free (id);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
/**
Packit Service c6b9b0
 * tpaw_irc_network_manager_remove:
Packit Service c6b9b0
 * @manager: an #TpawIrcNetworkManager
Packit Service c6b9b0
 * @network: the #TpawIrcNetwork to remove
Packit Service c6b9b0
 *
Packit Service c6b9b0
 * Remove an #TpawIrcNetwork from the given #TpawIrcNetworkManager.
Packit Service c6b9b0
 *
Packit Service c6b9b0
 */
Packit Service c6b9b0
void
Packit Service c6b9b0
tpaw_irc_network_manager_remove (TpawIrcNetworkManager *self,
Packit Service c6b9b0
                                    TpawIrcNetwork *network)
Packit Service c6b9b0
{
Packit Service c6b9b0
  g_return_if_fail (TPAW_IS_IRC_NETWORK_MANAGER (self));
Packit Service c6b9b0
  g_return_if_fail (TPAW_IS_IRC_NETWORK (network));
Packit Service c6b9b0
Packit Service c6b9b0
  network->user_defined = TRUE;
Packit Service c6b9b0
  network->dropped = TRUE;
Packit Service c6b9b0
Packit Service c6b9b0
  self->priv->have_to_save = TRUE;
Packit Service c6b9b0
  reset_save_timeout (self);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
append_active_networks_to_list (const gchar *id,
Packit Service c6b9b0
                        TpawIrcNetwork *network,
Packit Service c6b9b0
                        GSList **list)
Packit Service c6b9b0
{
Packit Service c6b9b0
  if (network->dropped)
Packit Service c6b9b0
    return;
Packit Service c6b9b0
Packit Service c6b9b0
  *list = g_slist_prepend (*list, g_object_ref (network));
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
append_dropped_networks_to_list (const gchar *id,
Packit Service c6b9b0
                        TpawIrcNetwork *network,
Packit Service c6b9b0
                        GSList **list)
Packit Service c6b9b0
{
Packit Service c6b9b0
  if (!network->dropped)
Packit Service c6b9b0
    return;
Packit Service c6b9b0
Packit Service c6b9b0
  *list = g_slist_prepend (*list, g_object_ref (network));
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static GSList *
Packit Service c6b9b0
get_network_list (TpawIrcNetworkManager *self,
Packit Service c6b9b0
    gboolean get_active)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GSList *irc_networks = NULL;
Packit Service c6b9b0
Packit Service c6b9b0
  g_return_val_if_fail (TPAW_IS_IRC_NETWORK_MANAGER (self), NULL);
Packit Service c6b9b0
Packit Service c6b9b0
  if (get_active)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      g_hash_table_foreach (self->priv->networks,
Packit Service c6b9b0
          (GHFunc) append_active_networks_to_list, &irc_networks);
Packit Service c6b9b0
    }
Packit Service c6b9b0
  else
Packit Service c6b9b0
    {
Packit Service c6b9b0
      g_hash_table_foreach (self->priv->networks,
Packit Service c6b9b0
          (GHFunc) append_dropped_networks_to_list, &irc_networks);
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  return irc_networks;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
/**
Packit Service c6b9b0
 * tpaw_irc_network_manager_get_networks:
Packit Service c6b9b0
 * @manager: an #TpawIrcNetworkManager
Packit Service c6b9b0
 *
Packit Service c6b9b0
 * Get the list of #TpawIrcNetwork associated with the given
Packit Service c6b9b0
 * manager.
Packit Service c6b9b0
 *
Packit Service c6b9b0
 * Returns: a new #GSList of refed #TpawIrcNetwork
Packit Service c6b9b0
 */
Packit Service c6b9b0
GSList *
Packit Service c6b9b0
tpaw_irc_network_manager_get_networks (TpawIrcNetworkManager *self)
Packit Service c6b9b0
{
Packit Service c6b9b0
  return get_network_list (self, TRUE);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
/**
Packit Service c6b9b0
 * tpaw_irc_network_manager_get_dropped_networks:
Packit Service c6b9b0
 * @manager: an #TpawIrcNetworkManager
Packit Service c6b9b0
 *
Packit Service c6b9b0
 * Get the list of dropped #TpawIrcNetworks associated with the given
Packit Service c6b9b0
 * manager.
Packit Service c6b9b0
 *
Packit Service c6b9b0
 * Returns: a new #GSList of refed dropped #TpawIrcNetworks
Packit Service c6b9b0
 */
Packit Service c6b9b0
GSList *
Packit Service c6b9b0
tpaw_irc_network_manager_get_dropped_networks (TpawIrcNetworkManager *self)
Packit Service c6b9b0
{
Packit Service c6b9b0
  return get_network_list (self, FALSE);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
/*
Packit Service c6b9b0
 * API to save/load and parse the irc_networks file.
Packit Service c6b9b0
 */
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
load_global_file (TpawIrcNetworkManager *self)
Packit Service c6b9b0
{
Packit Service c6b9b0
  if (self->priv->global_file == NULL)
Packit Service c6b9b0
    return;
Packit Service c6b9b0
Packit Service c6b9b0
  if (!g_file_test (self->priv->global_file, G_FILE_TEST_EXISTS))
Packit Service c6b9b0
    {
Packit Service c6b9b0
      DEBUG ("Global networks file %s doesn't exist",
Packit Service c6b9b0
          self->priv->global_file);
Packit Service c6b9b0
      return;
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  irc_network_manager_file_parse (self, self->priv->global_file, FALSE);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
load_user_file (TpawIrcNetworkManager *self)
Packit Service c6b9b0
{
Packit Service c6b9b0
  if (self->priv->user_file == NULL)
Packit Service c6b9b0
    return;
Packit Service c6b9b0
Packit Service c6b9b0
  if (!g_file_test (self->priv->user_file, G_FILE_TEST_EXISTS))
Packit Service c6b9b0
    {
Packit Service c6b9b0
      DEBUG ("User networks file %s doesn't exist", self->priv->global_file);
Packit Service c6b9b0
      return;
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  irc_network_manager_file_parse (self, self->priv->user_file, TRUE);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
irc_network_manager_load_servers (TpawIrcNetworkManager *self)
Packit Service c6b9b0
{
Packit Service c6b9b0
  self->priv->loading = TRUE;
Packit Service c6b9b0
Packit Service c6b9b0
  load_global_file (self);
Packit Service c6b9b0
  load_user_file (self);
Packit Service c6b9b0
Packit Service c6b9b0
  self->priv->loading = FALSE;
Packit Service c6b9b0
  self->priv->have_to_save = FALSE;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
irc_network_manager_parse_irc_server (TpawIrcNetwork *network,
Packit Service c6b9b0
                                      xmlNodePtr node)
Packit Service c6b9b0
{
Packit Service c6b9b0
  xmlNodePtr server_node;
Packit Service c6b9b0
Packit Service c6b9b0
  for (server_node = node->children; server_node;
Packit Service c6b9b0
      server_node = server_node->next)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      gchar *address = NULL, *port = NULL, *ssl = NULL;
Packit Service c6b9b0
Packit Service c6b9b0
      if (g_strcmp0 ((const gchar *) server_node->name, "server") != 0)
Packit Service c6b9b0
        continue;
Packit Service c6b9b0
Packit Service c6b9b0
      address = (gchar *) xmlGetProp (server_node, (const xmlChar *) "address");
Packit Service c6b9b0
      port = (gchar *) xmlGetProp (server_node, (const xmlChar *) "port");
Packit Service c6b9b0
      ssl = (gchar *) xmlGetProp (server_node, (const xmlChar *) "ssl");
Packit Service c6b9b0
Packit Service c6b9b0
      if (address != NULL)
Packit Service c6b9b0
        {
Packit Service c6b9b0
          gint port_nb = 0;
Packit Service c6b9b0
          gboolean have_ssl = FALSE;
Packit Service c6b9b0
          TpawIrcServer *server;
Packit Service c6b9b0
Packit Service c6b9b0
          if (port != NULL)
Packit Service c6b9b0
            port_nb = strtol (port, NULL, 10);
Packit Service c6b9b0
Packit Service c6b9b0
          if (port_nb <= 0 || port_nb > G_MAXUINT16)
Packit Service c6b9b0
            port_nb = 6667;
Packit Service c6b9b0
Packit Service c6b9b0
          if (ssl == NULL || g_strcmp0 (ssl, "TRUE") == 0)
Packit Service c6b9b0
            have_ssl = TRUE;
Packit Service c6b9b0
Packit Service c6b9b0
          DEBUG ("parsed server %s port %d ssl %d", address, port_nb, have_ssl);
Packit Service c6b9b0
Packit Service c6b9b0
          server = tpaw_irc_server_new (address, port_nb, have_ssl);
Packit Service c6b9b0
          tpaw_irc_network_append_server (network, server);
Packit Service c6b9b0
        }
Packit Service c6b9b0
Packit Service c6b9b0
      if (address)
Packit Service c6b9b0
        xmlFree (address);
Packit Service c6b9b0
      if (port)
Packit Service c6b9b0
        xmlFree (port);
Packit Service c6b9b0
      if (ssl)
Packit Service c6b9b0
        xmlFree (ssl);
Packit Service c6b9b0
    }
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
irc_network_manager_parse_irc_network (TpawIrcNetworkManager *self,
Packit Service c6b9b0
                                       xmlNodePtr node,
Packit Service c6b9b0
                                       gboolean user_defined)
Packit Service c6b9b0
{
Packit Service c6b9b0
  TpawIrcNetwork  *network;
Packit Service c6b9b0
  xmlNodePtr child;
Packit Service c6b9b0
  gchar *str;
Packit Service c6b9b0
  gchar *id, *name;
Packit Service c6b9b0
Packit Service c6b9b0
  id = (gchar *) xmlGetProp (node, (const xmlChar *) "id");
Packit Service c6b9b0
  if (xmlHasProp (node, (const xmlChar *) "dropped"))
Packit Service c6b9b0
    {
Packit Service c6b9b0
      if (!user_defined)
Packit Service c6b9b0
        {
Packit Service c6b9b0
          DEBUG ("the 'dropped' attribute shouldn't be used in the global file");
Packit Service c6b9b0
        }
Packit Service c6b9b0
Packit Service c6b9b0
      network = g_hash_table_lookup (self->priv->networks, id);
Packit Service c6b9b0
      if (network != NULL)
Packit Service c6b9b0
        {
Packit Service c6b9b0
          network->dropped = TRUE;
Packit Service c6b9b0
          network->user_defined = TRUE;
Packit Service c6b9b0
        }
Packit Service c6b9b0
       xmlFree (id);
Packit Service c6b9b0
      return;
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  if (!xmlHasProp (node, (const xmlChar *) "name"))
Packit Service c6b9b0
    return;
Packit Service c6b9b0
Packit Service c6b9b0
  name = (gchar *) xmlGetProp (node, (const xmlChar *) "name");
Packit Service c6b9b0
  network = tpaw_irc_network_new (name);
Packit Service c6b9b0
Packit Service c6b9b0
  if (xmlHasProp (node, (const xmlChar *) "network_charset"))
Packit Service c6b9b0
    {
Packit Service c6b9b0
      gchar *charset;
Packit Service c6b9b0
      charset = (gchar *) xmlGetProp (node, (const xmlChar *) "network_charset");
Packit Service c6b9b0
      g_object_set (network, "charset", charset, NULL);
Packit Service c6b9b0
      xmlFree (charset);
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  add_network (self, network, id);
Packit Service c6b9b0
  DEBUG ("add network %s (id %s)", name, id);
Packit Service c6b9b0
Packit Service c6b9b0
  for (child = node->children; child; child = child->next)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      gchar *tag;
Packit Service c6b9b0
Packit Service c6b9b0
      tag = (gchar *) child->name;
Packit Service c6b9b0
      str = (gchar *) xmlNodeGetContent (child);
Packit Service c6b9b0
Packit Service c6b9b0
      if (!str)
Packit Service c6b9b0
        continue;
Packit Service c6b9b0
Packit Service c6b9b0
      if (g_strcmp0 (tag, "servers") == 0)
Packit Service c6b9b0
        {
Packit Service c6b9b0
          irc_network_manager_parse_irc_server (network, child);
Packit Service c6b9b0
        }
Packit Service c6b9b0
Packit Service c6b9b0
      xmlFree (str);
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  network->user_defined = user_defined;
Packit Service c6b9b0
  g_object_unref (network);
Packit Service c6b9b0
  xmlFree (name);
Packit Service c6b9b0
  xmlFree (id);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static gboolean
Packit Service c6b9b0
irc_network_manager_file_parse (TpawIrcNetworkManager *self,
Packit Service c6b9b0
                                const gchar *filename,
Packit Service c6b9b0
                                gboolean user_defined)
Packit Service c6b9b0
{
Packit Service c6b9b0
  xmlParserCtxtPtr ctxt;
Packit Service c6b9b0
  xmlDocPtr doc;
Packit Service c6b9b0
  xmlNodePtr networks;
Packit Service c6b9b0
  xmlNodePtr node;
Packit Service c6b9b0
Packit Service c6b9b0
  DEBUG ("Attempting to parse file:'%s'...", filename);
Packit Service c6b9b0
Packit Service c6b9b0
  ctxt = xmlNewParserCtxt ();
Packit Service c6b9b0
Packit Service c6b9b0
  /* Parse and validate the file. */
Packit Service c6b9b0
  doc = xmlCtxtReadFile (ctxt, filename, NULL, 0);
Packit Service c6b9b0
  if (!doc)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      g_warning ("Failed to parse file:'%s'", filename);
Packit Service c6b9b0
      xmlFreeParserCtxt (ctxt);
Packit Service c6b9b0
      return FALSE;
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  if (!tpaw_xml_validate_from_resource (doc, IRC_NETWORKS_DTD_RESOURCENAME)) {
Packit Service c6b9b0
    g_warning ("Failed to validate file:'%s'", filename);
Packit Service c6b9b0
    xmlFreeDoc (doc);
Packit Service c6b9b0
    xmlFreeParserCtxt (ctxt);
Packit Service c6b9b0
    return FALSE;
Packit Service c6b9b0
  }
Packit Service c6b9b0
Packit Service c6b9b0
  /* The root node, networks. */
Packit Service c6b9b0
  networks = xmlDocGetRootElement (doc);
Packit Service c6b9b0
Packit Service c6b9b0
  for (node = networks->children; node; node = node->next)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      irc_network_manager_parse_irc_network (self, node, user_defined);
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  xmlFreeDoc (doc);
Packit Service c6b9b0
  xmlFreeParserCtxt (ctxt);
Packit Service c6b9b0
Packit Service c6b9b0
  return TRUE;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static void
Packit Service c6b9b0
write_network_to_xml (const gchar *id,
Packit Service c6b9b0
                      TpawIrcNetwork *network,
Packit Service c6b9b0
                      xmlNodePtr root)
Packit Service c6b9b0
{
Packit Service c6b9b0
  xmlNodePtr network_node, servers_node;
Packit Service c6b9b0
  GSList *servers, *l;
Packit Service c6b9b0
  gchar *name, *charset;
Packit Service c6b9b0
Packit Service c6b9b0
  if (!network->user_defined)
Packit Service c6b9b0
    /* no need to write this network to the XML */
Packit Service c6b9b0
    return;
Packit Service c6b9b0
Packit Service c6b9b0
  network_node = xmlNewChild (root, NULL, (const xmlChar *) "network", NULL);
Packit Service c6b9b0
  xmlNewProp (network_node, (const xmlChar *) "id", (const xmlChar *) id);
Packit Service c6b9b0
Packit Service c6b9b0
  if (network->dropped)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      xmlNewProp (network_node, (const xmlChar *) "dropped",
Packit Service c6b9b0
          (const xmlChar *)  "1");
Packit Service c6b9b0
      return;
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  g_object_get (network,
Packit Service c6b9b0
      "name", &name,
Packit Service c6b9b0
      "charset", &charset,
Packit Service c6b9b0
      NULL);
Packit Service c6b9b0
  xmlNewProp (network_node, (const xmlChar *) "name", (const xmlChar *) name);
Packit Service c6b9b0
  xmlNewProp (network_node, (const xmlChar *) "network_charset",
Packit Service c6b9b0
      (const xmlChar *) charset);
Packit Service c6b9b0
  g_free (name);
Packit Service c6b9b0
  g_free (charset);
Packit Service c6b9b0
Packit Service c6b9b0
  servers = tpaw_irc_network_get_servers (network);
Packit Service c6b9b0
Packit Service c6b9b0
  servers_node = xmlNewChild (network_node, NULL, (const xmlChar *) "servers",
Packit Service c6b9b0
      NULL);
Packit Service c6b9b0
  for (l = servers; l != NULL; l = g_slist_next (l))
Packit Service c6b9b0
    {
Packit Service c6b9b0
      TpawIrcServer *server;
Packit Service c6b9b0
      xmlNodePtr server_node;
Packit Service c6b9b0
      gchar *address, *tmp;
Packit Service c6b9b0
      guint port;
Packit Service c6b9b0
      gboolean ssl;
Packit Service c6b9b0
Packit Service c6b9b0
      server = l->data;
Packit Service c6b9b0
Packit Service c6b9b0
      server_node = xmlNewChild (servers_node, NULL, (const xmlChar *) "server",
Packit Service c6b9b0
          NULL);
Packit Service c6b9b0
Packit Service c6b9b0
      g_object_get (server,
Packit Service c6b9b0
          "address", &address,
Packit Service c6b9b0
          "port", &port,
Packit Service c6b9b0
          "ssl", &ssl,
Packit Service c6b9b0
          NULL);
Packit Service c6b9b0
Packit Service c6b9b0
      xmlNewProp (server_node, (const xmlChar *) "address",
Packit Service c6b9b0
          (const xmlChar *) address);
Packit Service c6b9b0
Packit Service c6b9b0
      tmp = g_strdup_printf ("%u", port);
Packit Service c6b9b0
      xmlNewProp (server_node, (const xmlChar *) "port",
Packit Service c6b9b0
          (const xmlChar *) tmp);
Packit Service c6b9b0
      g_free (tmp);
Packit Service c6b9b0
Packit Service c6b9b0
      xmlNewProp (server_node, (const xmlChar *) "ssl",
Packit Service c6b9b0
          ssl ? (const xmlChar *) "TRUE": (const xmlChar *) "FALSE");
Packit Service c6b9b0
Packit Service c6b9b0
      g_free (address);
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  /* free the list */
Packit Service c6b9b0
  g_slist_foreach (servers, (GFunc) g_object_unref, NULL);
Packit Service c6b9b0
  g_slist_free (servers);
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static gboolean
Packit Service c6b9b0
irc_network_manager_file_save (TpawIrcNetworkManager *self)
Packit Service c6b9b0
{
Packit Service c6b9b0
  xmlDocPtr doc;
Packit Service c6b9b0
  xmlNodePtr root;
Packit Service c6b9b0
Packit Service c6b9b0
  if (self->priv->user_file == NULL)
Packit Service c6b9b0
    {
Packit Service c6b9b0
      DEBUG ("can't save: no user file defined");
Packit Service c6b9b0
      return FALSE;
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  DEBUG ("Saving IRC networks");
Packit Service c6b9b0
Packit Service c6b9b0
  doc = xmlNewDoc ((const xmlChar *)  "1.0");
Packit Service c6b9b0
  root = xmlNewNode (NULL, (const xmlChar *) "networks");
Packit Service c6b9b0
  xmlDocSetRootElement (doc, root);
Packit Service c6b9b0
Packit Service c6b9b0
  g_hash_table_foreach (self->priv->networks,
Packit Service c6b9b0
      (GHFunc) write_network_to_xml, root);
Packit Service c6b9b0
Packit Service c6b9b0
  /* Make sure the XML is indented properly */
Packit Service c6b9b0
  xmlIndentTreeOutput = 1;
Packit Service c6b9b0
Packit Service c6b9b0
  xmlSaveFormatFileEnc (self->priv->user_file, doc, "utf-8", 1);
Packit Service c6b9b0
  xmlFreeDoc (doc);
Packit Service c6b9b0
Packit Service c6b9b0
  xmlMemoryDump ();
Packit Service c6b9b0
Packit Service c6b9b0
  self->priv->have_to_save = FALSE;
Packit Service c6b9b0
Packit Service c6b9b0
  return TRUE;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
static gboolean
Packit Service c6b9b0
find_network_by_address (const gchar *id,
Packit Service c6b9b0
                         TpawIrcNetwork *network,
Packit Service c6b9b0
                         const gchar *address)
Packit Service c6b9b0
{
Packit Service c6b9b0
  GSList *servers, *l;
Packit Service c6b9b0
  gboolean found = FALSE;
Packit Service c6b9b0
Packit Service c6b9b0
  if (network->dropped)
Packit Service c6b9b0
    return FALSE;
Packit Service c6b9b0
Packit Service c6b9b0
  servers = tpaw_irc_network_get_servers (network);
Packit Service c6b9b0
Packit Service c6b9b0
  for (l = servers; l != NULL && !found; l = g_slist_next (l))
Packit Service c6b9b0
    {
Packit Service c6b9b0
      TpawIrcServer *server = l->data;
Packit Service c6b9b0
      gchar *_address;
Packit Service c6b9b0
Packit Service c6b9b0
      g_object_get (server, "address", &_address, NULL);
Packit Service c6b9b0
      found = (_address != NULL && g_strcmp0 (address, _address) == 0);
Packit Service c6b9b0
Packit Service c6b9b0
      g_free (_address);
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  g_slist_foreach (servers, (GFunc) g_object_unref, NULL);
Packit Service c6b9b0
  g_slist_free (servers);
Packit Service c6b9b0
Packit Service c6b9b0
  return found;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
/**
Packit Service c6b9b0
 * tpaw_irc_network_manager_find_network_by_address:
Packit Service c6b9b0
 * @manager: an #TpawIrcNetworkManager
Packit Service c6b9b0
 * @address: the server address to look for
Packit Service c6b9b0
 *
Packit Service c6b9b0
 * Find the #TpawIrcNetwork which owns an #TpawIrcServer
Packit Service c6b9b0
 * that has the given address.
Packit Service c6b9b0
 *
Packit Service c6b9b0
 * Returns: the found #TpawIrcNetwork, or %NULL if not found.
Packit Service c6b9b0
 */
Packit Service c6b9b0
TpawIrcNetwork *
Packit Service c6b9b0
tpaw_irc_network_manager_find_network_by_address (
Packit Service c6b9b0
    TpawIrcNetworkManager *self,
Packit Service c6b9b0
    const gchar *address)
Packit Service c6b9b0
{
Packit Service c6b9b0
  TpawIrcNetwork *network;
Packit Service c6b9b0
Packit Service c6b9b0
  g_return_val_if_fail (address != NULL, NULL);
Packit Service c6b9b0
Packit Service c6b9b0
  network = g_hash_table_find (self->priv->networks,
Packit Service c6b9b0
      (GHRFunc) find_network_by_address, (gchar *) address);
Packit Service c6b9b0
Packit Service c6b9b0
  return network;
Packit Service c6b9b0
}
Packit Service c6b9b0
Packit Service c6b9b0
TpawIrcNetworkManager *
Packit Service c6b9b0
tpaw_irc_network_manager_dup_default (void)
Packit Service c6b9b0
{
Packit Service c6b9b0
  static TpawIrcNetworkManager *default_mgr = NULL;
Packit Service c6b9b0
  gchar *dir, *user_file_with_path, *global_file_with_path;
Packit Service c6b9b0
Packit Service c6b9b0
  if (default_mgr != NULL)
Packit Service c6b9b0
    return g_object_ref (default_mgr);
Packit Service c6b9b0
Packit Service c6b9b0
  dir = g_build_filename (g_get_user_config_dir (), PACKAGE_NAME, NULL);
Packit Service c6b9b0
  g_mkdir_with_parents (dir, S_IRUSR | S_IWUSR | S_IXUSR);
Packit Service c6b9b0
  user_file_with_path = g_build_filename (dir, IRC_NETWORKS_FILENAME, NULL);
Packit Service c6b9b0
  g_free (dir);
Packit Service c6b9b0
Packit Service c6b9b0
  global_file_with_path = g_build_filename (g_getenv ("TPAW_SRCDIR"),
Packit Service c6b9b0
      "tp-account-widgets", IRC_NETWORKS_FILENAME, NULL);
Packit Service c6b9b0
  if (!g_file_test (global_file_with_path, G_FILE_TEST_EXISTS))
Packit Service c6b9b0
    {
Packit Service c6b9b0
      g_free (global_file_with_path);
Packit Service c6b9b0
      global_file_with_path = g_build_filename (DATADIR, "empathy",
Packit Service c6b9b0
          IRC_NETWORKS_FILENAME, NULL);
Packit Service c6b9b0
    }
Packit Service c6b9b0
Packit Service c6b9b0
  default_mgr = tpaw_irc_network_manager_new (
Packit Service c6b9b0
      global_file_with_path, user_file_with_path);
Packit Service c6b9b0
Packit Service c6b9b0
  g_object_add_weak_pointer (G_OBJECT (default_mgr), (gpointer *) &default_mgr);
Packit Service c6b9b0
Packit Service c6b9b0
  g_free (global_file_with_path);
Packit Service c6b9b0
  g_free (user_file_with_path);
Packit Service c6b9b0
  return default_mgr;
Packit Service c6b9b0
}