summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLemonBoy <thatlemon@gmail.com>2015-12-06 22:31:49 +0100
committerLemonBoy <thatlemon@gmail.com>2015-12-09 00:34:39 +0100
commit750df38e8ccd59d7cb3a11e09a682755060f7283 (patch)
treeda657d6414bc1b0e74767b988d3a4185c9a65e05 /src
parentb5cfa55d9be3d7cd74628215ba5dd126c4e18342 (diff)
downloadirssi-750df38e8ccd59d7cb3a11e09a682755060f7283.zip
Rewrite some faulty logic handling the saved channels.
Issue #340 brought to our attention the fact that under certain circumstances irssi would go on a wild rampage and carelessly overwrite some saved channel records in the configuration file. This happened because the code didn't take into account the case where the channel index in setupchannels wouldn't match the one in the configuration; this actually happens when the user removes a chatnet without removing the associated channels.
Diffstat (limited to 'src')
-rw-r--r--src/core/channels-setup.c45
1 files changed, 37 insertions, 8 deletions
diff --git a/src/core/channels-setup.c b/src/core/channels-setup.c
index 2902ef8e..33f58022 100644
--- a/src/core/channels-setup.c
+++ b/src/core/channels-setup.c
@@ -30,16 +30,34 @@
GSList *setupchannels;
+static int compare_channel_name (CONFIG_NODE *node, CHANNEL_SETUP_REC *channel)
+{
+ char *name, *chatnet;
+
+ name = config_node_get_str(node, "name", NULL);
+ chatnet = config_node_get_str(node, "chatnet", NULL);
+
+ if (name == NULL || chatnet == NULL)
+ return 1;
+
+ return !!strcmp(name, channel->name) | !!strcmp(chatnet, channel->chatnet);
+}
+
static void channel_setup_save(CHANNEL_SETUP_REC *channel)
{
CONFIG_NODE *parentnode, *node;
- int index;
-
- index = g_slist_index(setupchannels, channel);
+ GSList *config_node;
parentnode = iconfig_node_traverse("(channels", TRUE);
- node = config_node_nth(parentnode, index);
- if (node == NULL)
+
+ /* Try to find this channel in the configuration */
+ config_node = g_slist_find_custom(parentnode->value, channel,
+ (GCompareFunc)compare_channel_name);
+ if (config_node != NULL)
+ /* Let's update this channel record */
+ node = config_node->data;
+ else
+ /* Create a brand-new channel record */
node = iconfig_node_section(parentnode, NULL, NODE_TYPE_BLOCK);
iconfig_node_clear(node);
@@ -65,10 +83,21 @@ void channel_setup_create(CHANNEL_SETUP_REC *channel)
static void channel_config_remove(CHANNEL_SETUP_REC *channel)
{
- CONFIG_NODE *node;
+ CONFIG_NODE *parentnode;
+ GSList *config_node;
- node = iconfig_node_traverse("channels", FALSE);
- if (node != NULL) iconfig_node_list_remove(node, g_slist_index(setupchannels, channel));
+ parentnode = iconfig_node_traverse("channels", FALSE);
+
+ if (parentnode == NULL)
+ return;
+
+ /* Try to find this channel in the configuration */
+ config_node = g_slist_find_custom(parentnode->value, channel,
+ (GCompareFunc)compare_channel_name);
+
+ if (config_node != NULL)
+ /* Delete the channel from the configuration */
+ iconfig_node_remove(parentnode, config_node->data);
}
static void channel_setup_destroy(CHANNEL_SETUP_REC *channel)