aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy
diff options
context:
space:
mode:
authorXavier Claessens <xclaesse@src.gnome.org>2008-02-18 07:38:19 +0800
committerXavier Claessens <xclaesse@src.gnome.org>2008-02-18 07:38:19 +0800
commit8107cb72c02be53157fc87955b4bc4f454662182 (patch)
treec37e04a560b3c654a5b509e2dd02c5a79178bed1 /libempathy
parent20c9a85036f7c951eb24df9587db695895869342 (diff)
downloadgsoc2013-empathy-8107cb72c02be53157fc87955b4bc4f454662182.tar
gsoc2013-empathy-8107cb72c02be53157fc87955b4bc4f454662182.tar.gz
gsoc2013-empathy-8107cb72c02be53157fc87955b4bc4f454662182.tar.bz2
gsoc2013-empathy-8107cb72c02be53157fc87955b4bc4f454662182.tar.lz
gsoc2013-empathy-8107cb72c02be53157fc87955b4bc4f454662182.tar.xz
gsoc2013-empathy-8107cb72c02be53157fc87955b4bc4f454662182.tar.zst
gsoc2013-empathy-8107cb72c02be53157fc87955b4bc4f454662182.zip
Merge commit 'cassidy/irc'
svn path=/trunk/; revision=649
Diffstat (limited to 'libempathy')
-rw-r--r--libempathy/Makefile.am20
-rw-r--r--libempathy/empathy-irc-network-manager.c801
-rw-r--r--libempathy/empathy-irc-network-manager.h82
-rw-r--r--libempathy/empathy-irc-network.c365
-rw-r--r--libempathy/empathy-irc-network.h81
-rw-r--r--libempathy/empathy-irc-networks.dtd18
-rw-r--r--libempathy/empathy-irc-server.c233
-rw-r--r--libempathy/empathy-irc-server.h65
-rw-r--r--libempathy/irc-networks.xml543
9 files changed, 2204 insertions, 4 deletions
diff --git a/libempathy/Makefile.am b/libempathy/Makefile.am
index 5d0c021b2..b952be270 100644
--- a/libempathy/Makefile.am
+++ b/libempathy/Makefile.am
@@ -41,7 +41,10 @@ libempathy_la_SOURCES = \
empathy-chandler.c \
empathy-filter.c \
empathy-idle.c \
- empathy-log-manager.c
+ empathy-log-manager.c \
+ empathy-irc-network-manager.c \
+ empathy-irc-network.c \
+ empathy-irc-server.c
# do not distribute generated files
nodist_libempathy_la_SOURCES =\
@@ -78,7 +81,10 @@ libempathy_headers = \
empathy-chandler.h \
empathy-filter.h \
empathy-idle.h \
- empathy-log-manager.h
+ empathy-log-manager.h \
+ empathy-irc-network-manager.h \
+ empathy-irc-network.h \
+ empathy-irc-server.h
libempathy_includedir = $(includedir)/libempathy/
libempathy_include_HEADERS = \
@@ -154,12 +160,17 @@ dtddir = $(datadir)/empathy
dtd_DATA = \
empathy-status-presets.dtd \
empathy-contact-groups.dtd \
- empathy-chatroom-manager.dtd
+ empathy-chatroom-manager.dtd \
+ empathy-irc-networks.dtd
stylesheetdir = $(datadir)/empathy
stylesheet_DATA = \
empathy-log-manager.xsl
+ircnetworksdir = $(datadir)/empathy
+ircnetworks_DATA = \
+ irc-networks.xml
+
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libempathy.pc
@@ -169,7 +180,8 @@ EXTRA_DIST = \
empathy-filter.xml \
tp-stream-engine.xml \
$(stylesheet_DATA) \
- $(dtd_DATA)
+ $(dtd_DATA) \
+ $(ircnetworks_DATA)
CLEANFILES = \
$(BUILT_SOURCES) \
diff --git a/libempathy/empathy-irc-network-manager.c b/libempathy/empathy-irc-network-manager.c
new file mode 100644
index 000000000..f88b93bc7
--- /dev/null
+++ b/libempathy/empathy-irc-network-manager.c
@@ -0,0 +1,801 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ *
+ * 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
+ *
+ * Authors: Guillaume Desmottes <gdesmott@gnome.org>
+ */
+
+#include <config.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include <libempathy/empathy-debug.h>
+
+#include "empathy-utils.h"
+#include "empathy-irc-network-manager.h"
+
+#define DEBUG_DOMAIN "IrcNetworkManager"
+#define IRC_NETWORKS_DTD_FILENAME "empathy-irc-networks.dtd"
+#define SAVE_TIMER 4
+
+G_DEFINE_TYPE (EmpathyIrcNetworkManager, empathy_irc_network_manager,
+ G_TYPE_OBJECT);
+
+/* properties */
+enum
+{
+ PROP_GLOBAL_FILE = 1,
+ PROP_USER_FILE,
+ LAST_PROPERTY
+};
+
+typedef struct _EmpathyIrcNetworkManagerPrivate
+ EmpathyIrcNetworkManagerPrivate;
+
+struct _EmpathyIrcNetworkManagerPrivate {
+ GHashTable *networks;
+
+ gchar *global_file;
+ gchar *user_file;
+ guint last_id;
+
+ /* Do we have to save modifications to the user file ? */
+ gboolean have_to_save;
+ /* Are we loading networks from XML files ? */
+ gboolean loading;
+ /* source id of the autosave timer */
+ gint save_timer_id;
+};
+
+#define EMPATHY_IRC_NETWORK_MANAGER_GET_PRIVATE(obj)\
+ ((EmpathyIrcNetworkManagerPrivate *) obj->priv)
+
+static void irc_network_manager_load_servers (
+ EmpathyIrcNetworkManager *manager);
+static gboolean irc_network_manager_file_parse (
+ EmpathyIrcNetworkManager *manager, const gchar *filename,
+ gboolean user_defined);
+static gboolean irc_network_manager_file_save (
+ EmpathyIrcNetworkManager *manager);
+
+static void
+empathy_irc_network_manager_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyIrcNetworkManager *self = EMPATHY_IRC_NETWORK_MANAGER (object);
+ EmpathyIrcNetworkManagerPrivate *priv =
+ EMPATHY_IRC_NETWORK_MANAGER_GET_PRIVATE (self);
+
+ switch (property_id)
+ {
+ case PROP_GLOBAL_FILE:
+ g_value_set_string (value, priv->global_file);
+ break;
+ case PROP_USER_FILE:
+ g_value_set_string (value, priv->user_file);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+empathy_irc_network_manager_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyIrcNetworkManager *self = EMPATHY_IRC_NETWORK_MANAGER (object);
+ EmpathyIrcNetworkManagerPrivate *priv =
+ EMPATHY_IRC_NETWORK_MANAGER_GET_PRIVATE (self);
+
+ switch (property_id)
+ {
+ case PROP_GLOBAL_FILE:
+ g_free (priv->global_file);
+ priv->global_file = g_value_dup_string (value);
+ break;
+ case PROP_USER_FILE:
+ g_free (priv->user_file);
+ priv->user_file = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static GObject *
+empathy_irc_network_manager_constructor (GType type,
+ guint n_props,
+ GObjectConstructParam *props)
+{
+ GObject *obj;
+ EmpathyIrcNetworkManager *self;
+
+ /* Parent constructor chain */
+ obj = G_OBJECT_CLASS (empathy_irc_network_manager_parent_class)->
+ constructor (type, n_props, props);
+
+ self = EMPATHY_IRC_NETWORK_MANAGER (obj);
+ irc_network_manager_load_servers (self);
+
+ return obj;
+}
+
+static void
+empathy_irc_network_manager_finalize (GObject *object)
+{
+ EmpathyIrcNetworkManager *self = EMPATHY_IRC_NETWORK_MANAGER (object);
+ EmpathyIrcNetworkManagerPrivate *priv =
+ EMPATHY_IRC_NETWORK_MANAGER_GET_PRIVATE (self);
+
+ if (priv->save_timer_id > 0)
+ {
+ g_source_remove (priv->save_timer_id);
+ }
+
+ if (priv->have_to_save)
+ {
+ irc_network_manager_file_save (self);
+ }
+
+ g_free (priv->global_file);
+ g_free (priv->user_file);
+
+ g_hash_table_destroy (priv->networks);
+
+ G_OBJECT_CLASS (empathy_irc_network_manager_parent_class)->finalize (object);
+}
+
+static void
+empathy_irc_network_manager_init (EmpathyIrcNetworkManager *self)
+{
+ EmpathyIrcNetworkManagerPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ EMPATHY_TYPE_IRC_NETWORK_MANAGER, EmpathyIrcNetworkManagerPrivate);
+
+ self->priv = priv;
+
+ priv->networks = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free, (GDestroyNotify) g_object_unref);
+
+ priv->last_id = 0;
+
+ priv->have_to_save = FALSE;
+ priv->loading = FALSE;
+ priv->save_timer_id = 0;
+}
+
+static void
+empathy_irc_network_manager_class_init (EmpathyIrcNetworkManagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GParamSpec *param_spec;
+
+ object_class->constructor = empathy_irc_network_manager_constructor;
+ object_class->get_property = empathy_irc_network_manager_get_property;
+ object_class->set_property = empathy_irc_network_manager_set_property;
+
+ g_type_class_add_private (object_class,
+ sizeof (EmpathyIrcNetworkManagerPrivate));
+
+ object_class->finalize = empathy_irc_network_manager_finalize;
+
+ param_spec = g_param_spec_string (
+ "global-file",
+ "path of the global networks file",
+ "The path of the system-wide filename from which we have to load"
+ " the networks list",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB);
+ g_object_class_install_property (object_class, PROP_GLOBAL_FILE, param_spec);
+
+ param_spec = g_param_spec_string (
+ "user-file",
+ "path of the user networks file",
+ "The path of user's filename from which we have to load"
+ " the networks list and to which we'll save his modifications",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB);
+ g_object_class_install_property (object_class, PROP_USER_FILE, param_spec);
+}
+
+/**
+ * empathy_irc_network_manager_new:
+ * @global_file: the path of the global networks file, or %NULL
+ * @user_file: the path of the user networks file, or %NULL
+ *
+ * Creates a new #EmpathyIrcNetworkManager
+ *
+ * Returns: a new #EmpathyIrcNetworkManager
+ */
+EmpathyIrcNetworkManager *
+empathy_irc_network_manager_new (const gchar *global_file,
+ const gchar *user_file)
+{
+ EmpathyIrcNetworkManager *manager;
+
+ manager = g_object_new (EMPATHY_TYPE_IRC_NETWORK_MANAGER,
+ "global-file", global_file,
+ "user-file", user_file,
+ NULL);
+
+ return manager;
+}
+
+static gboolean
+save_timeout (EmpathyIrcNetworkManager *self)
+{
+ EmpathyIrcNetworkManagerPrivate *priv =
+ EMPATHY_IRC_NETWORK_MANAGER_GET_PRIVATE (self);
+
+ priv->save_timer_id = 0;
+ irc_network_manager_file_save (self);
+
+ return FALSE;
+}
+
+static void
+reset_save_timeout (EmpathyIrcNetworkManager *self)
+{
+ EmpathyIrcNetworkManagerPrivate *priv =
+ EMPATHY_IRC_NETWORK_MANAGER_GET_PRIVATE (self);
+
+ if (priv->save_timer_id > 0)
+ {
+ g_source_remove (priv->save_timer_id);
+ }
+
+ priv->save_timer_id = g_timeout_add_seconds (SAVE_TIMER,
+ (GSourceFunc) save_timeout, self);
+}
+
+static void
+network_modified (EmpathyIrcNetwork *network,
+ EmpathyIrcNetworkManager *self)
+{
+ EmpathyIrcNetworkManagerPrivate *priv =
+ EMPATHY_IRC_NETWORK_MANAGER_GET_PRIVATE (self);
+
+ network->user_defined = TRUE;
+
+ if (!priv->loading)
+ {
+ priv->have_to_save = TRUE;
+ reset_save_timeout (self);
+ }
+}
+
+static void
+add_network (EmpathyIrcNetworkManager *self,
+ EmpathyIrcNetwork *network,
+ const gchar *id)
+{
+ EmpathyIrcNetworkManagerPrivate *priv =
+ EMPATHY_IRC_NETWORK_MANAGER_GET_PRIVATE (self);
+
+ g_hash_table_insert (priv->networks, g_strdup (id), g_object_ref (network));
+
+ g_signal_connect (network, "modified", G_CALLBACK (network_modified), self);
+}
+
+/**
+ * empathy_irc_network_manager_add:
+ * @manager: an #EmpathyIrcNetworkManager
+ * @network: the #EmpathyIrcNetwork to add
+ *
+ * Add an #EmpathyIrcNetwork to the given #EmpathyIrcNetworkManager.
+ *
+ */
+void
+empathy_irc_network_manager_add (EmpathyIrcNetworkManager *self,
+ EmpathyIrcNetwork *network)
+{
+ EmpathyIrcNetworkManagerPrivate *priv;
+ gchar *id = NULL;
+
+ g_return_if_fail (EMPATHY_IS_IRC_NETWORK_MANAGER (self));
+ g_return_if_fail (EMPATHY_IS_IRC_NETWORK (network));
+
+ priv = EMPATHY_IRC_NETWORK_MANAGER_GET_PRIVATE (self);
+
+ /* generate an id for this network */
+ do
+ {
+ g_free (id);
+ id = g_strdup_printf ("id%u", ++priv->last_id);
+ } while (g_hash_table_lookup (priv->networks, id) != NULL &&
+ priv->last_id < G_MAXUINT);
+
+ if (priv->last_id == G_MAXUINT)
+ {
+ empathy_debug (DEBUG_DOMAIN,
+ "Can't add network: too many networks using a similiar ID");
+ return;
+ }
+
+ empathy_debug (DEBUG_DOMAIN, "add server with \"%s\" as ID", id);
+
+ network->user_defined = TRUE;
+ add_network (self, network, id);
+
+ priv->have_to_save = TRUE;
+ reset_save_timeout (self);
+
+ g_free (id);
+}
+
+/**
+ * empathy_irc_network_manager_remove:
+ * @manager: an #EmpathyIrcNetworkManager
+ * @network: the #EmpathyIrcNetwork to remove
+ *
+ * Remove an #EmpathyIrcNetwork from the given #EmpathyIrcNetworkManager.
+ *
+ */
+void
+empathy_irc_network_manager_remove (EmpathyIrcNetworkManager *self,
+ EmpathyIrcNetwork *network)
+{
+ EmpathyIrcNetworkManagerPrivate *priv;
+
+ g_return_if_fail (EMPATHY_IS_IRC_NETWORK_MANAGER (self));
+ g_return_if_fail (EMPATHY_IS_IRC_NETWORK (network));
+
+ priv = EMPATHY_IRC_NETWORK_MANAGER_GET_PRIVATE (self);
+
+ network->user_defined = TRUE;
+ network->dropped = TRUE;
+
+ priv->have_to_save = TRUE;
+ reset_save_timeout (self);
+}
+
+static void
+append_network_to_list (const gchar *id,
+ EmpathyIrcNetwork *network,
+ GSList **list)
+{
+ if (network->dropped)
+ return;
+
+ *list = g_slist_prepend (*list, g_object_ref (network));
+}
+
+/**
+ * empathy_irc_network_manager_get_networks:
+ * @manager: an #EmpathyIrcNetworkManager
+ *
+ * Get the list of #EmpathyIrcNetwork associated with the given
+ * manager.
+ *
+ * Returns: a new #GSList of refed #EmpathyIrcNetwork
+ */
+GSList *
+empathy_irc_network_manager_get_networks (EmpathyIrcNetworkManager *self)
+{
+ EmpathyIrcNetworkManagerPrivate *priv;
+ GSList *irc_networks = NULL;
+
+ g_return_val_if_fail (EMPATHY_IS_IRC_NETWORK_MANAGER (self), NULL);
+
+ priv = EMPATHY_IRC_NETWORK_MANAGER_GET_PRIVATE (self);
+
+ g_hash_table_foreach (priv->networks, (GHFunc) append_network_to_list,
+ &irc_networks);
+
+ return irc_networks;
+}
+
+/*
+ * API to save/load and parse the irc_networks file.
+ */
+
+static void
+load_global_file (EmpathyIrcNetworkManager *self)
+{
+ EmpathyIrcNetworkManagerPrivate *priv =
+ EMPATHY_IRC_NETWORK_MANAGER_GET_PRIVATE (self);
+
+ if (priv->global_file == NULL)
+ return;
+
+ if (!g_file_test (priv->global_file, G_FILE_TEST_EXISTS))
+ {
+ empathy_debug (DEBUG_DOMAIN, "Global networks file %s doesn't exist",
+ priv->global_file);
+ return;
+ }
+
+ irc_network_manager_file_parse (self, priv->global_file, FALSE);
+}
+
+static void
+load_user_file (EmpathyIrcNetworkManager *self)
+{
+ EmpathyIrcNetworkManagerPrivate *priv =
+ EMPATHY_IRC_NETWORK_MANAGER_GET_PRIVATE (self);
+
+ if (priv->user_file == NULL)
+ return;
+
+ if (!g_file_test (priv->user_file, G_FILE_TEST_EXISTS))
+ {
+ empathy_debug (DEBUG_DOMAIN, "User networks file %s doesn't exist",
+ priv->global_file);
+ return;
+ }
+
+ irc_network_manager_file_parse (self, priv->user_file, TRUE);
+}
+
+static void
+irc_network_manager_load_servers (EmpathyIrcNetworkManager *self)
+{
+ EmpathyIrcNetworkManagerPrivate *priv =
+ EMPATHY_IRC_NETWORK_MANAGER_GET_PRIVATE (self);
+
+ priv->loading = TRUE;
+
+ load_global_file (self);
+ load_user_file (self);
+
+ priv->loading = FALSE;
+ priv->have_to_save = FALSE;
+}
+
+static void
+irc_network_manager_parse_irc_server (EmpathyIrcNetwork *network,
+ xmlNodePtr node)
+{
+ xmlNodePtr server_node;
+
+ for (server_node = node->children; server_node;
+ server_node = server_node->next)
+ {
+ gchar *address = NULL, *port = NULL, *ssl = NULL;
+
+ if (strcmp (server_node->name, "server") != 0)
+ continue;
+
+ address = xmlGetProp (server_node, "address");
+ port = xmlGetProp (server_node, "port");
+ ssl = xmlGetProp (server_node, "ssl");
+
+ if (address != NULL)
+ {
+ gint port_nb = 0;
+ gboolean have_ssl = FALSE;
+ EmpathyIrcServer *server;
+
+ if (port != NULL)
+ port_nb = strtol (port, NULL, 10);
+
+ if (port_nb <= 0 || port_nb > G_MAXUINT16)
+ port_nb = 6667;
+
+ if (ssl == NULL || strcmp (ssl, "TRUE") == 0)
+ have_ssl = TRUE;
+
+ empathy_debug (DEBUG_DOMAIN, "parsed server %s port %d ssl %d",
+ address, port_nb, have_ssl);
+
+ server = empathy_irc_server_new (address, port_nb, have_ssl);
+ empathy_irc_network_append_server (network, server);
+ }
+
+ if (address)
+ xmlFree (address);
+ if (port)
+ xmlFree (port);
+ if (ssl)
+ xmlFree (ssl);
+ }
+}
+
+static void
+irc_network_manager_parse_irc_network (EmpathyIrcNetworkManager *self,
+ xmlNodePtr node,
+ gboolean user_defined)
+{
+ EmpathyIrcNetworkManagerPrivate *priv =
+ EMPATHY_IRC_NETWORK_MANAGER_GET_PRIVATE (self);
+ EmpathyIrcNetwork *network;
+ xmlNodePtr child;
+ gchar *str;
+ gchar *id, *name;
+
+ id = xmlGetProp (node, "id");
+ if (xmlHasProp (node, "dropped"))
+ {
+ if (!user_defined)
+ {
+ empathy_debug (DEBUG_DOMAIN, "the \"dropped\" attribute shouldn't be"
+ " used in the global file");
+ }
+
+ network = g_hash_table_lookup (priv->networks, id);
+ if (network != NULL)
+ {
+ network->dropped = TRUE;
+ network->user_defined = TRUE;
+ }
+ xmlFree (id);
+ return;
+ }
+
+ if (!xmlHasProp (node, "name"))
+ return;
+
+ name = xmlGetProp (node, "name");
+ network = empathy_irc_network_new (name);
+
+ if (xmlHasProp (node, "network_charset"))
+ {
+ gchar *charset;
+ charset = xmlGetProp (node, "network_charset");
+ g_object_set (network, "charset", charset, NULL);
+ xmlFree (charset);
+ }
+
+ add_network (self, network, id);
+ empathy_debug (DEBUG_DOMAIN, "add network %s (id %s)", name, id);
+
+ for (child = node->children; child; child = child->next)
+ {
+ gchar *tag;
+
+ tag = (gchar *) child->name;
+ str = (gchar *) xmlNodeGetContent (child);
+
+ if (!str)
+ continue;
+
+ if (strcmp (tag, "servers") == 0)
+ {
+ irc_network_manager_parse_irc_server (network, child);
+ }
+
+ xmlFree (str);
+ }
+
+ network->user_defined = user_defined;
+ g_object_unref (network);
+ xmlFree (name);
+ xmlFree (id);
+}
+
+static gboolean
+irc_network_manager_file_parse (EmpathyIrcNetworkManager *self,
+ const gchar *filename,
+ gboolean user_defined)
+{
+ EmpathyIrcNetworkManagerPrivate *priv;
+ xmlParserCtxtPtr ctxt;
+ xmlDocPtr doc;
+ xmlNodePtr networks;
+ xmlNodePtr node;
+
+ priv = EMPATHY_IRC_NETWORK_MANAGER_GET_PRIVATE (self);
+
+ empathy_debug (DEBUG_DOMAIN, "Attempting to parse file:'%s'...", filename);
+
+ ctxt = xmlNewParserCtxt ();
+
+ /* Parse and validate the file. */
+ doc = xmlCtxtReadFile (ctxt, filename, NULL, 0);
+ if (!doc)
+ {
+ g_warning ("Failed to parse file:'%s'", filename);
+ xmlFreeParserCtxt (ctxt);
+ return FALSE;
+ }
+
+ if (!empathy_xml_validate (doc, IRC_NETWORKS_DTD_FILENAME)) {
+ g_warning ("Failed to validate file:'%s'", filename);
+ xmlFreeDoc (doc);
+ xmlFreeParserCtxt (ctxt);
+ return FALSE;
+ }
+
+ /* The root node, networks. */
+ networks = xmlDocGetRootElement (doc);
+
+ for (node = networks->children; node; node = node->next)
+ {
+ irc_network_manager_parse_irc_network (self, node, user_defined);
+ }
+
+ xmlFreeDoc(doc);
+ xmlFreeParserCtxt (ctxt);
+
+ return TRUE;
+}
+
+static void
+write_network_to_xml (const gchar *id,
+ EmpathyIrcNetwork *network,
+ xmlNodePtr root)
+{
+ xmlNodePtr network_node, servers_node;
+ GSList *servers, *l;
+ gchar *name, *charset;
+
+ if (!network->user_defined)
+ /* no need to write this network to the XML */
+ return;
+
+ network_node = xmlNewChild (root, NULL, "network", NULL);
+ xmlNewProp (network_node, "id", id);
+
+ if (network->dropped)
+ {
+ xmlNewProp (network_node, "dropped", "1");
+ return;
+ }
+
+ g_object_get (network,
+ "name", &name,
+ "charset", &charset,
+ NULL);
+ xmlNewProp (network_node, "name", name);
+ xmlNewProp (network_node, "network_charset", charset);
+ g_free (name);
+ g_free (charset);
+
+ servers = empathy_irc_network_get_servers (network);
+
+ servers_node = xmlNewChild (network_node, NULL, "servers", NULL);
+ for (l = servers; l != NULL; l = g_slist_next (l))
+ {
+ EmpathyIrcServer *server;
+ xmlNodePtr server_node;
+ gchar *address, *tmp;
+ guint port;
+ gboolean ssl;
+
+ server = l->data;
+
+ server_node = xmlNewChild (servers_node, NULL, "server", NULL);
+
+ g_object_get (server,
+ "address", &address,
+ "port", &port,
+ "ssl", &ssl,
+ NULL);
+
+ xmlNewProp (server_node, "address", address);
+
+ tmp = g_strdup_printf ("%u", port);
+ xmlNewProp (server_node, "port", tmp);
+ g_free (tmp);
+
+ xmlNewProp (server_node, "ssl", ssl ? "TRUE": "FALSE");
+
+ g_free (address);
+ }
+
+ /* free the list */
+ g_slist_foreach (servers, (GFunc) g_object_unref, NULL);
+ g_slist_free (servers);
+}
+
+static gboolean
+irc_network_manager_file_save (EmpathyIrcNetworkManager *self)
+{
+ EmpathyIrcNetworkManagerPrivate *priv =
+ EMPATHY_IRC_NETWORK_MANAGER_GET_PRIVATE (self);
+ xmlDocPtr doc;
+ xmlNodePtr root;
+
+ if (priv->user_file == NULL)
+ {
+ empathy_debug (DEBUG_DOMAIN, "can't save: no user file defined");
+ return FALSE;
+ }
+
+ empathy_debug (DEBUG_DOMAIN, "Saving IRC networks");
+
+ doc = xmlNewDoc ("1.0");
+ root = xmlNewNode (NULL, "networks");
+ xmlDocSetRootElement (doc, root);
+
+ g_hash_table_foreach (priv->networks, (GHFunc) write_network_to_xml, root);
+
+ /* Make sure the XML is indented properly */
+ xmlIndentTreeOutput = 1;
+
+ xmlSaveFormatFileEnc (priv->user_file, doc, "utf-8", 1);
+ xmlFreeDoc (doc);
+
+ xmlCleanupParser ();
+ xmlMemoryDump ();
+
+ priv->have_to_save = FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+find_network_by_address (const gchar *id,
+ EmpathyIrcNetwork *network,
+ const gchar *address)
+{
+ GSList *servers, *l;
+ gboolean found = FALSE;
+
+ if (network->dropped)
+ return FALSE;
+
+ servers = empathy_irc_network_get_servers (network);
+
+ for (l = servers; l != NULL && !found; l = g_slist_next (l))
+ {
+ EmpathyIrcServer *server = l->data;
+ gchar *_address;
+
+ g_object_get (server, "address", &_address, NULL);
+ found = (_address != NULL && strcmp (address, _address) == 0);
+
+ g_free (_address);
+ }
+
+ g_slist_foreach (servers, (GFunc) g_object_unref, NULL);
+ g_slist_free (servers);
+
+ return found;
+}
+
+/**
+ * empathy_irc_network_manager_find_network_by_address:
+ * @manager: an #EmpathyIrcNetworkManager
+ * @address: the server address to look for
+ *
+ * Find the #EmpathyIrcNetwork which owns an #EmpathyIrcServer
+ * that has the given address.
+ *
+ * Returns: the found #EmpathyIrcNetwork, or %NULL if not found.
+ */
+EmpathyIrcNetwork *
+empathy_irc_network_manager_find_network_by_address (
+ EmpathyIrcNetworkManager *self,
+ const gchar *address)
+{
+ EmpathyIrcNetworkManagerPrivate *priv =
+ EMPATHY_IRC_NETWORK_MANAGER_GET_PRIVATE (self);
+ EmpathyIrcNetwork *network;
+
+ g_return_val_if_fail (address != NULL, NULL);
+
+ network = g_hash_table_find (priv->networks,
+ (GHRFunc) find_network_by_address, (gchar *) address);
+
+ return network;
+}
diff --git a/libempathy/empathy-irc-network-manager.h b/libempathy/empathy-irc-network-manager.h
new file mode 100644
index 000000000..a853a074b
--- /dev/null
+++ b/libempathy/empathy-irc-network-manager.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ *
+ * 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
+ *
+ * Authors: Guillaume Desmottes <gdesmott@gnome.org>
+ */
+
+#ifndef __EMPATHY_IRC_NETWORK_MANAGER_H__
+#define __EMPATHY_IRC_NETWORK_MANAGER_H__
+
+#include <glib-object.h>
+
+#include "empathy-irc-network.h"
+
+G_BEGIN_DECLS
+
+typedef struct _EmpathyIrcNetworkManager EmpathyIrcNetworkManager;
+typedef struct _EmpathyIrcNetworkManagerClass EmpathyIrcNetworkManagerClass;
+
+struct _EmpathyIrcNetworkManager
+{
+ GObject parent;
+
+ gpointer priv;
+};
+
+struct _EmpathyIrcNetworkManagerClass
+{
+ GObjectClass parent_class;
+};
+
+GType
+empathy_irc_network_manager_get_type (void);
+
+/* TYPE MACROS */
+#define EMPATHY_TYPE_IRC_NETWORK_MANAGER \
+ (empathy_irc_network_manager_get_type ())
+#define EMPATHY_IRC_NETWORK_MANAGER(o) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_IRC_NETWORK_MANAGER, \
+ EmpathyIrcNetworkManager))
+#define EMPATHY_IRC_NETWORK_MANAGER_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_CAST ((k), EMPATHY_TYPE_IRC_NETWORK_MANAGER, \
+ EmpathyIrcNetworkManagerClass))
+#define EMPATHY_IS_IRC_NETWORK_MANAGER(o) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_IRC_NETWORK_MANAGER))
+#define EMPATHY_IS_IRC_NETWORK_MANAGER_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_IRC_NETWORK_MANAGER))
+#define EMPATHY_IRC_NETWORK_MANAGER_GET_CLASS(o) \
+ (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_IRC_NETWORK_MANAGER, \
+ EmpathyIrcNetworkManagerClass))
+
+EmpathyIrcNetworkManager * empathy_irc_network_manager_new (
+ const gchar *global_file, const gchar *user_file);
+
+void empathy_irc_network_manager_add (EmpathyIrcNetworkManager *manager,
+ EmpathyIrcNetwork *network);
+
+void empathy_irc_network_manager_remove (EmpathyIrcNetworkManager *manager,
+ EmpathyIrcNetwork *network);
+
+GSList * empathy_irc_network_manager_get_networks (
+ EmpathyIrcNetworkManager *manager);
+
+EmpathyIrcNetwork * empathy_irc_network_manager_find_network_by_address (
+ EmpathyIrcNetworkManager *manager, const gchar *address);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_IRC_NETWORK_MANAGER_H__ */
diff --git a/libempathy/empathy-irc-network.c b/libempathy/empathy-irc-network.c
new file mode 100644
index 000000000..f754adef6
--- /dev/null
+++ b/libempathy/empathy-irc-network.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2007 Guillaume Desmottes
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Guillaume Desmottes <gdesmott@gnome.org>
+ */
+
+#include <config.h>
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include <telepathy-glib/util.h>
+
+#include "empathy-marshal.h"
+#include "empathy-irc-network.h"
+
+G_DEFINE_TYPE (EmpathyIrcNetwork, empathy_irc_network, G_TYPE_OBJECT);
+
+/* properties */
+enum
+{
+ PROP_NAME = 1,
+ PROP_CHARSET,
+ LAST_PROPERTY
+};
+
+/* signals */
+enum
+{
+ MODIFIED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+typedef struct _EmpathyIrcNetworkPrivate EmpathyIrcNetworkPrivate;
+
+struct _EmpathyIrcNetworkPrivate
+{
+ gchar *name;
+ gchar *charset;
+ GSList *servers;
+};
+
+#define EMPATHY_IRC_NETWORK_GET_PRIVATE(obj)\
+ ((EmpathyIrcNetworkPrivate *) obj->priv)
+
+static void
+server_modified_cb (EmpathyIrcServer *server,
+ EmpathyIrcNetwork *self)
+{
+ g_signal_emit (self, signals[MODIFIED], 0);
+}
+
+static void
+empathy_irc_network_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyIrcNetwork *self = EMPATHY_IRC_NETWORK (object);
+ EmpathyIrcNetworkPrivate *priv = EMPATHY_IRC_NETWORK_GET_PRIVATE (self);
+
+ switch (property_id)
+ {
+ case PROP_NAME:
+ g_value_set_string (value, priv->name);
+ break;
+ case PROP_CHARSET:
+ g_value_set_string (value, priv->charset);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+empathy_irc_network_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyIrcNetwork *self = EMPATHY_IRC_NETWORK (object);
+ EmpathyIrcNetworkPrivate *priv = EMPATHY_IRC_NETWORK_GET_PRIVATE (self);
+
+ switch (property_id)
+ {
+ case PROP_NAME:
+ if (tp_strdiff (priv->name, g_value_get_string (value)))
+ {
+ g_free (priv->name);
+ priv->name = g_value_dup_string (value);
+ g_signal_emit (object, signals[MODIFIED], 0);
+ }
+ break;
+ case PROP_CHARSET:
+ if (tp_strdiff (priv->charset, g_value_get_string (value)))
+ {
+ g_free (priv->charset);
+ priv->charset = g_value_dup_string (value);
+ g_signal_emit (object, signals[MODIFIED], 0);
+ }
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+empathy_irc_network_dispose (GObject *object)
+{
+ EmpathyIrcNetwork *self = EMPATHY_IRC_NETWORK (object);
+ EmpathyIrcNetworkPrivate *priv = EMPATHY_IRC_NETWORK_GET_PRIVATE (self);
+ GSList *l;
+
+ for (l = priv->servers; l != NULL; l = g_slist_next (l))
+ {
+ g_signal_handlers_disconnect_by_func (l->data,
+ G_CALLBACK (server_modified_cb), self);
+ g_object_unref (l->data);
+ }
+
+ G_OBJECT_CLASS (empathy_irc_network_parent_class)->dispose (object);
+}
+
+static void
+empathy_irc_network_finalize (GObject *object)
+{
+ EmpathyIrcNetwork *self = EMPATHY_IRC_NETWORK (object);
+ EmpathyIrcNetworkPrivate *priv = EMPATHY_IRC_NETWORK_GET_PRIVATE (self);
+
+ g_slist_free (priv->servers);
+ g_free (priv->name);
+ g_free (priv->charset);
+
+ G_OBJECT_CLASS (empathy_irc_network_parent_class)->finalize (object);
+}
+
+static void
+empathy_irc_network_init (EmpathyIrcNetwork *self)
+{
+ EmpathyIrcNetworkPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ EMPATHY_TYPE_IRC_NETWORK, EmpathyIrcNetworkPrivate);
+
+ self->priv = priv;
+
+ priv->servers = NULL;
+
+ self->user_defined = TRUE;
+ self->dropped = FALSE;
+}
+
+static void
+empathy_irc_network_class_init (EmpathyIrcNetworkClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GParamSpec *param_spec;
+
+ object_class->get_property = empathy_irc_network_get_property;
+ object_class->set_property = empathy_irc_network_set_property;
+
+ g_type_class_add_private (object_class,
+ sizeof (EmpathyIrcNetworkPrivate));
+
+ object_class->dispose = empathy_irc_network_dispose;
+ object_class->finalize = empathy_irc_network_finalize;
+
+ param_spec = g_param_spec_string (
+ "name",
+ "Network name",
+ "The displayed name of this network",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB);
+ g_object_class_install_property (object_class, PROP_NAME, param_spec);
+
+ param_spec = g_param_spec_string (
+ "charset",
+ "Charset",
+ "The charset to use on this network",
+ "UTF-8",
+ G_PARAM_CONSTRUCT |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB);
+ g_object_class_install_property (object_class, PROP_CHARSET, param_spec);
+
+ /**
+ * EmpathyIrcNetwork::modified:
+ * @network: the object that received the signal
+ *
+ * Emitted when either a property or a server of the network is modified.
+ *
+ */
+ signals[MODIFIED] = g_signal_new (
+ "modified",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+/**
+ * empathy_irc_network_new:
+ * @name: the name of the network
+ *
+ * Creates a new #EmpathyIrcNetwork.
+ *
+ * Returns: a new #EmpathyIrcNetwork
+ */
+EmpathyIrcNetwork *
+empathy_irc_network_new (const gchar *name)
+{
+ return g_object_new (EMPATHY_TYPE_IRC_NETWORK,
+ "name", name,
+ NULL);
+}
+
+/**
+ * empathy_irc_network_get_servers:
+ * @network: an #EmpathyIrcNetwork
+ *
+ * Get the list of #EmpathyIrcServer that belongs to this network.
+ * These servers are sorted according their priority.
+ * So the first one will be the first used when trying to connect to
+ * the network.
+ *
+ * Returns: a new #GSList of refed #EmpathyIrcServer.
+ */
+GSList *
+empathy_irc_network_get_servers (EmpathyIrcNetwork *self)
+{
+ EmpathyIrcNetworkPrivate *priv;
+ GSList *servers = NULL, *l;
+
+ g_return_val_if_fail (EMPATHY_IS_IRC_NETWORK (self), NULL);
+ priv = EMPATHY_IRC_NETWORK_GET_PRIVATE (self);
+
+ for (l = priv->servers; l != NULL; l = g_slist_next (l))
+ {
+ servers = g_slist_prepend (servers, g_object_ref (l->data));
+ }
+
+ return g_slist_reverse (servers);
+}
+
+/**
+ * empathy_irc_network_append_server:
+ * @network: an #EmpathyIrcNetwork
+ * @server: the #EmpathyIrcServer to add
+ *
+ * Add an #EmpathyIrcServer to the given #EmpathyIrcNetwork. The server
+ * is added at the last position in network's servers list.
+ *
+ */
+void
+empathy_irc_network_append_server (EmpathyIrcNetwork *self,
+ EmpathyIrcServer *server)
+{
+ EmpathyIrcNetworkPrivate *priv;
+
+ g_return_if_fail (EMPATHY_IS_IRC_NETWORK (self));
+ g_return_if_fail (server != NULL && EMPATHY_IS_IRC_SERVER (server));
+
+ priv = EMPATHY_IRC_NETWORK_GET_PRIVATE (self);
+
+ g_return_if_fail (g_slist_find (priv->servers, server) == NULL);
+
+ priv->servers = g_slist_append (priv->servers, g_object_ref (server));
+
+ g_signal_connect (server, "modified", G_CALLBACK (server_modified_cb), self);
+
+ g_signal_emit (self, signals[MODIFIED], 0);
+}
+
+/**
+ * empathy_irc_network_remove_server:
+ * @network: an #EmpathyIrcNetwork
+ * @server: the #EmpathyIrcServer to remove
+ *
+ * Remove an #EmpathyIrcServer from the servers list of the
+ * given #EmpathyIrcNetwork.
+ *
+ */
+void
+empathy_irc_network_remove_server (EmpathyIrcNetwork *self,
+ EmpathyIrcServer *server)
+{
+ EmpathyIrcNetworkPrivate *priv;
+ GSList *l;
+
+ g_return_if_fail (EMPATHY_IS_IRC_NETWORK (self));
+ g_return_if_fail (server != NULL && EMPATHY_IS_IRC_SERVER (server));
+
+ priv = EMPATHY_IRC_NETWORK_GET_PRIVATE (self);
+
+ l = g_slist_find (priv->servers, server);
+ if (l == NULL)
+ return;
+
+ g_object_unref (l->data);
+ priv->servers = g_slist_delete_link (priv->servers, l);
+ g_signal_handlers_disconnect_by_func (server, G_CALLBACK (server_modified_cb),
+ self);
+
+ g_signal_emit (self, signals[MODIFIED], 0);
+}
+
+/**
+ * empathy_irc_network_set_server_position:
+ * @network: an #EmpathyIrcNetwork
+ * @server: the #EmpathyIrcServer to move
+ * @pos: the position to move the server. If this is negative, or is larger than
+ * the number of servers in the list, the server is moved to the end of the
+ * list.
+ *
+ * Move an #EmpathyIrcServer in the servers list of the given
+ * #EmpathyIrcNetwork.
+ *
+ */
+void
+empathy_irc_network_set_server_position (EmpathyIrcNetwork *self,
+ EmpathyIrcServer *server,
+ gint pos)
+{
+ EmpathyIrcNetworkPrivate *priv;
+ GSList *l;
+
+ g_return_if_fail (EMPATHY_IS_IRC_NETWORK (self));
+ g_return_if_fail (server != NULL && EMPATHY_IS_IRC_SERVER (server));
+
+ priv = EMPATHY_IRC_NETWORK_GET_PRIVATE (self);
+
+ l = g_slist_find (priv->servers, server);
+ if (l == NULL)
+ return;
+
+ priv->servers = g_slist_delete_link (priv->servers, l);
+ priv->servers = g_slist_insert (priv->servers, server, pos);
+
+ g_signal_emit (self, signals[MODIFIED], 0);
+}
diff --git a/libempathy/empathy-irc-network.h b/libempathy/empathy-irc-network.h
new file mode 100644
index 000000000..ac146a183
--- /dev/null
+++ b/libempathy/empathy-irc-network.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ *
+ * 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
+ *
+ * Authors: Guillaume Desmottes <gdesmott@gnome.org>
+ */
+
+#ifndef __EMPATHY_IRC_NETWORK_H__
+#define __EMPATHY_IRC_NETWORK_H__
+
+#include <glib-object.h>
+
+#include "empathy-irc-server.h"
+
+G_BEGIN_DECLS
+
+typedef struct _EmpathyIrcNetwork EmpathyIrcNetwork;
+typedef struct _EmpathyIrcNetworkClass EmpathyIrcNetworkClass;
+
+struct _EmpathyIrcNetwork
+{
+ GObject parent;
+
+ gpointer priv;
+
+ gboolean user_defined;
+ gboolean dropped;
+};
+
+struct _EmpathyIrcNetworkClass
+{
+ GObjectClass parent_class;
+};
+
+GType empathy_irc_network_get_type (void);
+
+/* TYPE MACROS */
+#define EMPATHY_TYPE_IRC_NETWORK (empathy_irc_network_get_type ())
+#define EMPATHY_IRC_NETWORK(o) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_IRC_NETWORK, \
+ EmpathyIrcNetwork))
+#define EMPATHY_IRC_NETWORK_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_CAST ((k), EMPATHY_TYPE_IRC_NETWORK,\
+ EmpathyIrcNetworkClass))
+#define EMPATHY_IS_IRC_NETWORK(o) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_IRC_NETWORK))
+#define EMPATHY_IS_IRC_NETWORK_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_IRC_NETWORK))
+#define EMPATHY_IRC_NETWORK_GET_CLASS(o) \
+ (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_IRC_NETWORK, \
+ EmpathyIrcNetworkClass))
+
+EmpathyIrcNetwork * empathy_irc_network_new (const gchar *name);
+
+GSList * empathy_irc_network_get_servers (EmpathyIrcNetwork *network);
+
+void empathy_irc_network_append_server (EmpathyIrcNetwork *network,
+ EmpathyIrcServer *server);
+
+void empathy_irc_network_remove_server (EmpathyIrcNetwork *network,
+ EmpathyIrcServer *server);
+
+void empathy_irc_network_set_server_position (EmpathyIrcNetwork *network,
+ EmpathyIrcServer *server, gint pos);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_IRC_NETWORK_H__ */
diff --git a/libempathy/empathy-irc-networks.dtd b/libempathy/empathy-irc-networks.dtd
new file mode 100644
index 000000000..692e613c1
--- /dev/null
+++ b/libempathy/empathy-irc-networks.dtd
@@ -0,0 +1,18 @@
+<!--
+ DTD for Empathys irc networks.
+ by Xavier Claessens <xclaesse@gmail.com>
+-->
+
+
+<!ELEMENT networks (network*)>
+<!ELEMENT network (servers*)>
+<!ATTLIST network id ID #REQUIRED>
+<!ATTLIST network name CDATA #IMPLIED>
+<!ATTLIST network network_charset CDATA #IMPLIED>
+<!ATTLIST network dropped CDATA #IMPLIED>
+
+<!ELEMENT servers (server*)>
+<!ELEMENT server EMPTY>
+<!ATTLIST server address CDATA #REQUIRED>
+<!ATTLIST server port CDATA #REQUIRED>
+<!ATTLIST server ssl CDATA #REQUIRED>
diff --git a/libempathy/empathy-irc-server.c b/libempathy/empathy-irc-server.c
new file mode 100644
index 000000000..510acc77b
--- /dev/null
+++ b/libempathy/empathy-irc-server.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ *
+ * 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
+ *
+ * Authors: Guillaume Desmottes <gdesmott@gnome.org>
+ */
+
+#include <config.h>
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include <telepathy-glib/util.h>
+
+#include "empathy-marshal.h"
+#include "empathy-irc-server.h"
+
+G_DEFINE_TYPE (EmpathyIrcServer, empathy_irc_server, G_TYPE_OBJECT);
+
+/* properties */
+enum
+{
+ PROP_ADDRESS = 1,
+ PROP_PORT,
+ PROP_SSL,
+ LAST_PROPERTY
+};
+
+/* signals */
+enum
+{
+ MODIFIED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+typedef struct _EmpathyIrcServerPrivate EmpathyIrcServerPrivate;
+
+struct _EmpathyIrcServerPrivate
+{
+ gchar *address;
+ gint port;
+ gboolean ssl;
+};
+
+#define EMPATHY_IRC_SERVER_GET_PRIVATE(obj)\
+ ((EmpathyIrcServerPrivate *) obj->priv)
+
+static void
+empathy_irc_server_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyIrcServer *self = EMPATHY_IRC_SERVER (object);
+ EmpathyIrcServerPrivate *priv = EMPATHY_IRC_SERVER_GET_PRIVATE (self);
+
+ switch (property_id)
+ {
+ case PROP_ADDRESS:
+ g_value_set_string (value, priv->address);
+ break;
+ case PROP_PORT:
+ g_value_set_uint (value, priv->port);
+ break;
+ case PROP_SSL:
+ g_value_set_boolean (value, priv->ssl);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+empathy_irc_server_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyIrcServer *self = EMPATHY_IRC_SERVER (object);
+ EmpathyIrcServerPrivate *priv = EMPATHY_IRC_SERVER_GET_PRIVATE (self);
+
+ switch (property_id)
+ {
+ case PROP_ADDRESS:
+ if (tp_strdiff (priv->address, g_value_get_string (value)))
+ {
+ g_free (priv->address);
+ priv->address = g_value_dup_string (value);
+ g_signal_emit (object, signals[MODIFIED], 0);
+ }
+ break;
+ case PROP_PORT:
+ if (priv->port != g_value_get_uint (value))
+ {
+ priv->port = g_value_get_uint (value);
+ g_signal_emit (object, signals[MODIFIED], 0);
+ }
+ break;
+ case PROP_SSL:
+ if (priv->ssl != g_value_get_boolean (value))
+ {
+ priv->ssl = g_value_get_boolean (value);
+ g_signal_emit (object, signals[MODIFIED], 0);
+ }
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+empathy_irc_server_finalize (GObject *object)
+{
+ EmpathyIrcServer *self = EMPATHY_IRC_SERVER (object);
+ EmpathyIrcServerPrivate *priv = EMPATHY_IRC_SERVER_GET_PRIVATE (self);
+
+ g_free (priv->address);
+
+ G_OBJECT_CLASS (empathy_irc_server_parent_class)->finalize (object);
+}
+
+static void
+empathy_irc_server_init (EmpathyIrcServer *self)
+{
+ EmpathyIrcServerPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ EMPATHY_TYPE_IRC_SERVER, EmpathyIrcServerPrivate);
+
+ self->priv = priv;
+}
+
+static void
+empathy_irc_server_class_init (EmpathyIrcServerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GParamSpec *param_spec;
+
+ object_class->get_property = empathy_irc_server_get_property;
+ object_class->set_property = empathy_irc_server_set_property;
+
+ g_type_class_add_private (object_class,
+ sizeof (EmpathyIrcServerPrivate));
+
+ object_class->finalize = empathy_irc_server_finalize;
+
+ param_spec = g_param_spec_string (
+ "address",
+ "Server address",
+ "The address of this server",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB);
+ g_object_class_install_property (object_class, PROP_ADDRESS, param_spec);
+
+ param_spec = g_param_spec_uint (
+ "port",
+ "Server port",
+ "The port to use to connect on this server",
+ 1, G_MAXUINT16, 6667,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB);
+ g_object_class_install_property (object_class, PROP_PORT, param_spec);
+
+ param_spec = g_param_spec_boolean (
+ "ssl",
+ "SSL",
+ "If this server needs SSL connection",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB);
+ g_object_class_install_property (object_class, PROP_SSL, param_spec);
+
+ /**
+ * EmpathyIrcServer::modified:
+ * @server: the object that received the signal
+ *
+ * Emitted when a property of the server is modified.
+ *
+ */
+ signals[MODIFIED] = g_signal_new (
+ "modified",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+/**
+ * empathy_irc_server_new:
+ * @address: the address
+ * @port: the port
+ * @ssl: %TRUE if the server needs a SSL connection
+ *
+ * Creates a new #EmpathyIrcServer
+ *
+ * Returns: a new #EmpathyIrcServer
+ */
+EmpathyIrcServer *
+empathy_irc_server_new (const gchar *address,
+ guint port,
+ gboolean ssl)
+{
+ return g_object_new (EMPATHY_TYPE_IRC_SERVER,
+ "address", address,
+ "port", port,
+ "ssl", ssl,
+ NULL);
+}
diff --git a/libempathy/empathy-irc-server.h b/libempathy/empathy-irc-server.h
new file mode 100644
index 000000000..09f8c1ef7
--- /dev/null
+++ b/libempathy/empathy-irc-server.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ *
+ * 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
+ *
+ * Authors: Guillaume Desmottes <gdesmott@gnome.org>
+ */
+
+#ifndef __EMPATHY_IRC_SERVER_H__
+#define __EMPATHY_IRC_SERVER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef struct _EmpathyIrcServer EmpathyIrcServer;
+typedef struct _EmpathyIrcServerClass EmpathyIrcServerClass;
+
+struct _EmpathyIrcServer
+{
+ GObject parent;
+
+ gpointer priv;
+};
+
+struct _EmpathyIrcServerClass
+{
+ GObjectClass parent_class;
+};
+
+GType empathy_irc_server_get_type (void);
+
+/* TYPE MACROS */
+#define EMPATHY_TYPE_IRC_SERVER (empathy_irc_server_get_type ())
+#define EMPATHY_IRC_SERVER(o) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_IRC_SERVER, EmpathyIrcServer))
+#define EMPATHY_IRC_SERVER_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_CAST ((k), EMPATHY_TYPE_IRC_SERVER, \
+ EmpathyIrcServerClass))
+#define EMPATHY_IS_IRC_SERVER(o) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_IRC_SERVER))
+#define EMPATHY_IS_IRC_SERVER_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_IRC_SERVER))
+#define EMPATHY_IRC_SERVER_GET_CLASS(o) \
+ (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_IRC_SERVER,\
+ EmpathyIrcServerClass))
+
+EmpathyIrcServer * empathy_irc_server_new (const gchar *address, guint port,
+ gboolean ssl);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_IRC_SERVER_H__ */
diff --git a/libempathy/irc-networks.xml b/libempathy/irc-networks.xml
new file mode 100644
index 000000000..383ba25ff
--- /dev/null
+++ b/libempathy/irc-networks.xml
@@ -0,0 +1,543 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<networks>
+ <network name="Debian Servers" id="debian_servers">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.debian.org"/>
+ <server ssl="FALSE" port="6667" address="irc.oftc.net"/>
+ </servers>
+ </network>
+ <network name="Ubuntu Servers" id="ubuntu_servers">
+ <servers>
+ <server ssl="FALSE" port="8001" address="irc.ubuntu.com"/>
+ </servers>
+ </network>
+ <network name="2600net" id="a2600net">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.2600.net"/>
+ </servers>
+ </network>
+ <network name="AccessIRC" id="accessirc">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.accessirc.net"/>
+ <server ssl="FALSE" port="6667" address="eu.accessirc.net"/>
+ </servers>
+ </network>
+ <network name="AfterNET" id="afternet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.afternet.org"/>
+ <server ssl="FALSE" port="6667" address="us.afternet.org"/>
+ <server ssl="FALSE" port="6667" address="eu.afternet.org"/>
+ </servers>
+ </network>
+ <network name="Aitvaras" id="aitvaras">
+ <servers>
+ <server ssl="TRUE" port="6668" address="irc.data.lt"/>
+ <server ssl="TRUE" port="6668" address="irc-ssl.omnitel.net"/>
+ <server ssl="TRUE" port="9999" address="irc-ssl.le.lt"/>
+ <server ssl="FALSE" port="6667" address="irc.data.lt"/>
+ <server ssl="FALSE" port="6667" address="irc.omnitel.net"/>
+ <server ssl="FALSE" port="6667" address="irc.ktu.lt"/>
+ <server ssl="FALSE" port="6667" address="irc.le.lt"/>
+ <server ssl="FALSE" port="6667" address="irc.takas.lt"/>
+ <server ssl="FALSE" port="6667" address="irc.5ci.net"/>
+ <server ssl="FALSE" port="6667" address="irc.kis.lt"/>
+ </servers>
+ </network>
+ <network name="AmigaNet" id="amiganet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.amiganet.org"/>
+ <server ssl="FALSE" port="6667" address="us.amiganet.org"/>
+ <server ssl="FALSE" port="6667" address="uk.amiganet.org"/>
+ </servers>
+ </network>
+ <network name="ARCNet" id="arcnet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="se1.arcnet.vapor.com"/>
+ <server ssl="FALSE" port="6667" address="us1.arcnet.vapor.com"/>
+ <server ssl="FALSE" port="6667" address="us2.arcnet.vapor.com"/>
+ <server ssl="FALSE" port="6667" address="us3.arcnet.vapor.com"/>
+ <server ssl="FALSE" port="6667" address="ca1.arcnet.vapor.com"/>
+ <server ssl="FALSE" port="6667" address="de1.arcnet.vapor.com"/>
+ <server ssl="FALSE" port="6667" address="de3.arcnet.vapor.com"/>
+ <server ssl="FALSE" port="6667" address="ch1.arcnet.vapor.com"/>
+ <server ssl="FALSE" port="6667" address="be1.arcnet.vapor.com"/>
+ <server ssl="FALSE" port="6667" address="nl3.arcnet.vapor.com"/>
+ <server ssl="FALSE" port="6667" address="uk1.arcnet.vapor.com"/>
+ <server ssl="FALSE" port="6667" address="uk2.arcnet.vapor.com"/>
+ <server ssl="FALSE" port="6667" address="fr1.arcnet.vapor.com"/>
+ </servers>
+ </network>
+ <network name="AstroLink" id="astrolink">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.astrolink.org"/>
+ </servers>
+ </network>
+ <network name="AustNet" id="austnet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="au.austnet.org"/>
+ <server ssl="FALSE" port="6667" address="us.austnet.org"/>
+ <server ssl="FALSE" port="6667" address="ca.austnet.org"/>
+ </servers>
+ </network>
+ <network name="AzzurraNet" id="azzurranet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.azzurra.org"/>
+ <server ssl="FALSE" port="6667" address="crypto.azzurra.org"/>
+ </servers>
+ </network>
+ <network name="Beirut" id="beirut">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.beirut.com"/>
+ </servers>
+ </network>
+ <network name="ChatJunkies" id="chatjunkies">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.chatjunkies.org"/>
+ <server ssl="FALSE" port="6667" address="nl.chatjunkies.org"/>
+ </servers>
+ </network>
+ <network name="ChatNet" id="chatnet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="US.ChatNet.Org"/>
+ <server ssl="FALSE" port="6667" address="EU.ChatNet.Org"/>
+ </servers>
+ </network>
+ <network name="ChatSociety" id="chatsociety">
+ <servers>
+ <server ssl="FALSE" port="6667" address="us.chatsociety.net"/>
+ <server ssl="FALSE" port="6667" address="eu.chatsociety.net"/>
+ </servers>
+ </network>
+ <network name="ChatSpike" id="chatspike">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.chatspike.net"/>
+ </servers>
+ </network>
+ <network name="ChillFactory" id="chillfactory">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.chillfactory.net"/>
+ </servers>
+ </network>
+ <network name="CoolChat" id="coolchat">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.coolchat.net"/>
+ </servers>
+ </network>
+ <network name="Criten" id="criten">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.criten.net"/>
+ <server ssl="FALSE" port="6667" address="irc.eu.criten.net"/>
+ </servers>
+ </network>
+ <network name="DALnet" id="dalnet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.dal.net"/>
+ <server ssl="FALSE" port="6667" address="irc.eu.dal.net"/>
+ </servers>
+ </network>
+ <network name="Dark-Tou-Net" id="dark-tou-net">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.d-t-net.de"/>
+ <server ssl="FALSE" port="6667" address="bw.d-t-net.de"/>
+ <server ssl="FALSE" port="6667" address="nc.d-t-net.de"/>
+ <server ssl="FALSE" port="6667" address="wakka.d-t-net.de"/>
+ </servers>
+ </network>
+ <network name="DarkMyst" id="darkmyst">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.darkmyst.org"/>
+ </servers>
+ </network>
+ <network name="DeepIRC" id="deepirc">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.deepirc.net"/>
+ </servers>
+ </network>
+ <network name="DeltaAnime" id="deltaanime">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.deltaanime.net"/>
+ </servers>
+ </network>
+ <network name="EFnet" id="efnet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.blackened.com"/>
+ <server ssl="FALSE" port="6667" address="irc.Prison.NET"/>
+ <server ssl="FALSE" port="6667" address="irc.Qeast.net"/>
+ <server ssl="FALSE" port="6667" address="irc.efnet.pl"/>
+ <server ssl="FALSE" port="6667" address="efnet.demon.co.uk"/>
+ <server ssl="FALSE" port="6667" address="irc.lightning.net"/>
+ <server ssl="FALSE" port="6667" address="irc.mindspring.com"/>
+ <server ssl="FALSE" port="6667" address="irc.easynews.com"/>
+ <server ssl="FALSE" port="6667" address="irc.servercentral.net"/>
+ </servers>
+ </network>
+ <network name="EnterTheGame" id="enterthegame">
+ <servers>
+ <server ssl="FALSE" port="6667" address="IRC.EnterTheGame.Com"/>
+ </servers>
+ </network>
+ <network name="EUIrc" id="euirc">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.euirc.net"/>
+ <server ssl="FALSE" port="6667" address="irc.ham.de.euirc.net"/>
+ <server ssl="FALSE" port="6667" address="irc.ber.de.euirc.net"/>
+ <server ssl="FALSE" port="6667" address="irc.ffm.de.euirc.net"/>
+ <server ssl="FALSE" port="6667" address="irc.bre.de.euirc.net"/>
+ <server ssl="FALSE" port="6667" address="irc.hes.de.euirc.net"/>
+ <server ssl="FALSE" port="6667" address="irc.vie.at.euirc.net"/>
+ <server ssl="FALSE" port="6667" address="irc.inn.at.euirc.net"/>
+ <server ssl="FALSE" port="6667" address="irc.bas.ch.euirc.net"/>
+ </servers>
+ </network>
+ <network name="EuropNet" id="europnet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.europnet.org"/>
+ </servers>
+ </network>
+ <network name="EU-IRC" id="eu-irc">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.eu-irc.net"/>
+ </servers>
+ </network>
+ <network name="FDFNet" id="fdfnet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.fdfnet.net"/>
+ <server ssl="FALSE" port="6667" address="irc.eu.fdfnet.net"/>
+ </servers>
+ </network>
+ <network name="FEFNet" id="fefnet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.fef.net"/>
+ <server ssl="FALSE" port="6667" address="irc.ggn.net"/>
+ <server ssl="FALSE" port="6667" address="irc.vendetta.com"/>
+ </servers>
+ </network>
+ <network name="FreeNode" id="freenode">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.freenode.net"/>
+ </servers>
+ </network>
+ <network name="GalaxyNet" id="galaxynet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.galaxynet.org"/>
+ </servers>
+ </network>
+ <network name="GamesNET" id="gamesnet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.gamesnet.net"/>
+ <server ssl="FALSE" port="6667" address="irc.ca.gamesnet.net"/>
+ <server ssl="FALSE" port="6667" address="irc.eu.gamesnet.net"/>
+ </servers>
+ </network>
+ <network name="German-Elite" id="german-elite">
+ <servers>
+ <server ssl="FALSE" port="6667" address="dominion.german-elite.net"/>
+ <server ssl="FALSE" port="6667" address="komatu.german-elite.net"/>
+ </servers>
+ </network>
+ <network name="GimpNet" id="gimpnet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.gimp.org"/>
+ <server ssl="FALSE" port="6667" address="irc.us.gimp.org"/>
+ </servers>
+ </network>
+ <network name="HabberNet" id="habbernet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.habber.net"/>
+ </servers>
+ </network>
+ <network name="Hashmark" id="hashmark">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.hashmark.net"/>
+ </servers>
+ </network>
+ <network name="IdleMonkeys" id="idlemonkeys">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.idlemonkeys.net"/>
+ </servers>
+ </network>
+ <network name="insiderZ.DE" id="insiderz.de">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.insiderz.de"/>
+ <server ssl="FALSE" port="6666" address="irc.insiderz.de"/>
+ </servers>
+ </network>
+ <network name="IrcLink" id="irclink">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.irclink.net"/>
+ <server ssl="FALSE" port="6667" address="Alesund.no.eu.irclink.net"/>
+ <server ssl="FALSE" port="6667" address="Oslo.no.eu.irclink.net"/>
+ <server ssl="FALSE" port="6667" address="frogn.no.eu.irclink.net"/>
+ <server ssl="FALSE" port="6667" address="tonsberg.no.eu.irclink.net"/>
+ </servers>
+ </network>
+ <network name="IRCNet" id="ircnet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.ircnet.com"/>
+ <server ssl="FALSE" port="6668" address="irc.stealth.net"/>
+ <server ssl="FALSE" port="6667" address="ircnet.demon.co.uk"/>
+ <server ssl="FALSE" port="6667" address="irc.datacomm.ch"/>
+ <server ssl="FALSE" port="6667" address="random.ircd.de"/>
+ <server ssl="FALSE" port="6667" address="ircnet.netvision.net.il"/>
+ <server ssl="FALSE" port="6667" address="irc.cs.hut.fi"/>
+ </servers>
+ </network>
+ <network name="Irctoo.net" id="irctoo.net">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.irctoo.net"/>
+ </servers>
+ </network>
+ <network name="Krstarica" id="krstarica">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.krstarica.com"/>
+ </servers>
+ </network>
+ <network name="Librenet" id="librenet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.librenet.net"/>
+ <server ssl="FALSE" port="6667" address="ielf.fr.librenet.net"/>
+ </servers>
+ </network>
+ <network name="LinkNet" id="linknet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.link-net.org"/>
+ <server ssl="FALSE" port="6667" address="irc.no.link-net.org"/>
+ <server ssl="FALSE" port="6667" address="irc.bahnhof.se"/>
+ </servers>
+ </network>
+ <network name="MagicStar" id="magicstar">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.magicstar.net"/>
+ </servers>
+ </network>
+ <network name="Majistic" id="majistic">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.majistic.net"/>
+ </servers>
+ </network>
+ <network name="MindForge" id="mindforge">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.mindforge.org"/>
+ </servers>
+ </network>
+ <network name="MIXXnet" id="mixxnet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.mixxnet.net"/>
+ </servers>
+ </network>
+ <network name="NeverNET" id="nevernet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.nevernet.net"/>
+ <server ssl="FALSE" port="6667" address="imagine.nevernet.net"/>
+ <server ssl="FALSE" port="6667" address="dimension.nevernet.net"/>
+ <server ssl="FALSE" port="6667" address="universe.nevernet.net"/>
+ <server ssl="FALSE" port="6667" address="wayland.nevernet.net"/>
+ <server ssl="FALSE" port="6667" address="forte.nevernet.net"/>
+ </servers>
+ </network>
+ <network name="NixHelpNet" id="nixhelpnet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.nixhelp.org"/>
+ <server ssl="FALSE" port="6667" address="us.nixhelp.org"/>
+ <server ssl="FALSE" port="6667" address="uk.nixhelp.org"/>
+ <server ssl="FALSE" port="6667" address="uk2.nixhelp.org"/>
+ <server ssl="FALSE" port="6667" address="uk3.nixhelp.org"/>
+ <server ssl="FALSE" port="6667" address="nl.nixhelp.org"/>
+ <server ssl="FALSE" port="6667" address="ca.ld.nixhelp.org"/>
+ <server ssl="FALSE" port="6667" address="us.co.nixhelp.org"/>
+ <server ssl="FALSE" port="6667" address="us.ca.nixhelp.org"/>
+ <server ssl="FALSE" port="6667" address="us.pa.nixhelp.org"/>
+ </servers>
+ </network>
+ <network name="NullusNet" id="nullusnet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.nullus.net"/>
+ </servers>
+ </network>
+ <network name="Oceanius" id="oceanius">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.oceanius.com"/>
+ </servers>
+ </network>
+ <network name="OFTC" id="oftc">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.oftc.net"/>
+ </servers>
+ </network>
+ <network name="OtherNet" id="othernet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.othernet.org"/>
+ </servers>
+ </network>
+ <network name="Oz.org" id="oz.org">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.oz.org"/>
+ <server ssl="FALSE" port="6667" address="germany.oz.org"/>
+ <server ssl="FALSE" port="6667" address="sandiego.oz.org"/>
+ <server ssl="FALSE" port="6667" address="us.oz.org"/>
+ <server ssl="FALSE" port="6667" address="au.oz.org"/>
+ <server ssl="FALSE" port="6667" address="rockhampton.oz.org"/>
+ <server ssl="FALSE" port="6667" address="wollongong.oz.org"/>
+ <server ssl="FALSE" port="6667" address="waix.oz.org"/>
+ </servers>
+ </network>
+ <network name="PTlink" id="ptlink">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.PTlink.net"/>
+ <server ssl="FALSE" port="6667" address="aaia.PTlink.net"/>
+ </servers>
+ </network>
+ <network name="PTNe" id="ptne">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.PTNet.org"/>
+ <server ssl="FALSE" port="6667" address="rccn.PTnet.org"/>
+ <server ssl="FALSE" port="6667" address="uevora.PTnet.org"/>
+ <server ssl="FALSE" port="6667" address="umoderna.PTnet.org"/>
+ <server ssl="FALSE" port="6667" address="ist.PTnet.org"/>
+ <server ssl="FALSE" port="6667" address="aaum.PTnet.org"/>
+ <server ssl="FALSE" port="6667" address="uc.PTnet.org"/>
+ <server ssl="FALSE" port="6667" address="ualg.ptnet.org"/>
+ <server ssl="FALSE" port="6667" address="madinfo.PTnet.org"/>
+ <server ssl="FALSE" port="6667" address="ua.PTnet.org"/>
+ <server ssl="FALSE" port="6667" address="ipg.PTnet.org"/>
+ <server ssl="FALSE" port="6667" address="isec.PTnet.org"/>
+ <server ssl="FALSE" port="6667" address="utad.PTnet.org"/>
+ <server ssl="FALSE" port="6667" address="iscte.PTnet.org"/>
+ <server ssl="FALSE" port="6667" address="ubi.PTnet.org"/>
+ </servers>
+ </network>
+ <network name="QuakeNet" id="quakenet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.quakenet.org"/>
+ <server ssl="FALSE" port="6667" address="irc.se.quakenet.org"/>
+ <server ssl="FALSE" port="6667" address="irc.dk.quakenet.org"/>
+ <server ssl="FALSE" port="6667" address="irc.no.quakenet.org"/>
+ <server ssl="FALSE" port="6667" address="irc.fi.quakenet.org"/>
+ <server ssl="FALSE" port="6667" address="irc.be.quakenet.org"/>
+ <server ssl="FALSE" port="6667" address="irc.uk.quakenet.org"/>
+ <server ssl="FALSE" port="6667" address="irc.de.quakenet.org"/>
+ <server ssl="FALSE" port="6667" address="irc.it.quakenet.org"/>
+ </servers>
+ </network>
+ <network name="RebelChat" id="rebelchat">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.rebelchat.org"/>
+ </servers>
+ </network>
+ <network name="RizeNET" id="rizenet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.rizenet.org"/>
+ <server ssl="FALSE" port="6667" address="omega.rizenet.org"/>
+ <server ssl="FALSE" port="6667" address="evelance.rizenet.org"/>
+ <server ssl="FALSE" port="6667" address="lisa.rizenet.org"/>
+ <server ssl="FALSE" port="6667" address="scott.rizenet.org"/>
+ </servers>
+ </network>
+ <network name="RusNet" id="rusnet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.tomsk.net"/>
+ <server ssl="FALSE" port="6667" address="irc.rinet.ru"/>
+ <server ssl="FALSE" port="6667" address="irc.run.net"/>
+ <server ssl="FALSE" port="6667" address="irc.ru"/>
+ <server ssl="FALSE" port="6667" address="irc.lucky.net"/>
+ </servers>
+ </network>
+ <network name="SceneNet" id="scenenet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.scene.org"/>
+ <server ssl="FALSE" port="6667" address="irc.eu.scene.org"/>
+ <server ssl="FALSE" port="6667" address="irc.us.scene.org"/>
+ </servers>
+ </network>
+ <network name="SlashNET" id="slashnet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.slashnet.org"/>
+ <server ssl="FALSE" port="6667" address="area51.slashnet.org"/>
+ <server ssl="FALSE" port="6667" address="moo.slashnet.org"/>
+ <server ssl="FALSE" port="6667" address="radon.slashnet.org"/>
+ </servers>
+ </network>
+ <network name="Sohbet.Net" id="sohbet.net">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.sohbet.net"/>
+ </servers>
+ </network>
+ <network name="SolidIRC" id="solidirc">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.solidirc.com"/>
+ </servers>
+ </network>
+ <network name="SorceryNet" id="sorcerynet">
+ <servers>
+ <server ssl="FALSE" port="9000" address="irc.sorcery.net"/>
+ <server ssl="FALSE" port="9000" address="irc.us.sorcery.net"/>
+ <server ssl="FALSE" port="9000" address="irc.eu.sorcery.net"/>
+ </servers>
+ </network>
+ <network name="Spidernet" id="spidernet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="us.spidernet.org"/>
+ <server ssl="FALSE" port="6667" address="eu.spidernet.org"/>
+ <server ssl="FALSE" port="6667" address="irc.spidernet.org"/>
+ </servers>
+ </network>
+ <network name="StarChat" id="starchat">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.starchat.net"/>
+ <server ssl="FALSE" port="6667" address="gainesville.starchat.net"/>
+ <server ssl="FALSE" port="6667" address="freebsd.starchat.net"/>
+ <server ssl="FALSE" port="6667" address="sunset.starchat.net"/>
+ <server ssl="FALSE" port="6667" address="revenge.starchat.net"/>
+ <server ssl="FALSE" port="6667" address="tahoma.starchat.net"/>
+ <server ssl="FALSE" port="6667" address="neo.starchat.net"/>
+ </servers>
+ </network>
+ <network name="TNI3" id="tni3">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.tni3.com"/>
+ </servers>
+ </network>
+ <network name="UnderNet" id="undernet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="us.undernet.org"/>
+ <server ssl="FALSE" port="6667" address="eu.undernet.org"/>
+ </servers>
+ </network>
+ <network name="UniBG" id="unibg">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.lirex.com"/>
+ <server ssl="FALSE" port="6667" address="irc.naturella.com"/>
+ <server ssl="FALSE" port="6667" address="irc.spnet.net"/>
+ <server ssl="FALSE" port="6667" address="irc.techno-link.com"/>
+ <server ssl="FALSE" port="6667" address="irc.telecoms.bg"/>
+ <server ssl="FALSE" port="6667" address="irc.tu-varna.edu"/>
+ </servers>
+ </network>
+ <network name="Whiffle" id="whiffle">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.whiffle.org"/>
+ </servers>
+ </network>
+ <network name="Worldnet" id="worldnet">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.worldnet.net"/>
+ <server ssl="FALSE" port="6667" address="irc.fr.worldnet.net"/>
+ </servers>
+ </network>
+ <network name="Xentonix.net" id="xentonix.net">
+ <servers>
+ <server ssl="FALSE" port="6667" address="irc.ffm.de.eu.xentonix.net"/>
+ <server ssl="FALSE" port="6667" address="irc.kar.de.eu.xentonix.net"/>
+ <server ssl="FALSE" port="6667" address="irc.vie.at.eu.xentonix.net"/>
+ </servers>
+ </network>
+ <network name="XWorld" id="xworld">
+ <servers>
+ <server ssl="FALSE" port="6667" address="Buffalo.NY.US.XWorld.org"/>
+ <server ssl="FALSE" port="6667" address="Minneapolis.MN.US.Xworld.Org"/>
+ <server ssl="FALSE" port="6667" address="Rochester.NY.US.XWorld.org"/>
+ <server ssl="FALSE" port="6667" address="Bayern.DE.EU.XWorld.Org"/>
+ <server ssl="FALSE" port="6667" address="Chicago.IL.US.XWorld.Org"/>
+ </servers>
+ </network>
+</networks>