summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorBerke Viktor <bviktor@hexchat.org>2013-05-14 16:40:32 +0200
committerBerke Viktor <bviktor@hexchat.org>2013-05-14 16:40:32 +0200
commita435e8648fa16c8f661626b055e0e6626bf26460 (patch)
tree5fce9360f1232168ec4f063076e98a5241717a07
parent7cdfeff20490971c40deed9f59697f0e524348c8 (diff)
Fix initial autojoins and some erroneous copies/frees
-rw-r--r--src/common/hexchat.h2
-rw-r--r--src/common/inbound.c35
-rw-r--r--src/common/proto-irc.c55
-rw-r--r--src/common/server.c2
-rw-r--r--src/common/servlist.c40
-rw-r--r--src/common/servlist.h5
6 files changed, 129 insertions, 10 deletions
diff --git a/src/common/hexchat.h b/src/common/hexchat.h
index 060fd082..5fdbfc45 100644
--- a/src/common/hexchat.h
+++ b/src/common/hexchat.h
@@ -479,7 +479,7 @@ typedef struct server
 	void (*p_ns_identify)(struct server *, char *pass);
 	void (*p_ns_ghost)(struct server *, char *usname, char *pass);
 	void (*p_join)(struct server *, char *channel, char *key);
-	void (*p_join_list)(struct server *, GSList *channels, GSList *keys);
+	void (*p_join_list)(struct server *, GSList *favorites);
 	void (*p_login)(struct server *, char *user, char *realname);
 	void (*p_join_info)(struct server *, char *channel);
 	void (*p_mode)(struct server *, char *target, char *mode);
diff --git a/src/common/inbound.c b/src/common/inbound.c
index f16c7b53..dd35ad1c 100644
--- a/src/common/inbound.c
+++ b/src/common/inbound.c
@@ -1066,10 +1066,10 @@ inbound_nameslist_end (server *serv, char *chan)
 	return FALSE;
 }
 
+#if 0//FIXME remove when finished porting
 static gboolean
 check_autojoin_channels (server *serv)
 {
-#if 0//FIXME
 	char *po;
 	session *sess;
 	GSList *list = sess_list;
@@ -1138,7 +1138,40 @@ check_autojoin_channels (server *serv)
 
 	serv->joindelay_tag = 0;
 	fe_server_event (serv, FE_SE_LOGGEDIN, i);
+	return FALSE;
+}
 #endif
+
+static gboolean
+check_autojoin_channels (server *serv)
+{
+	int i = 0;
+
+	/* shouldn't really happen, the io tag is destroyed in server.c */
+	if (!is_server (serv))
+	{
+		return FALSE;
+	}
+
+	/* send auto join list */
+	if (serv->favlist)
+	{
+		serv->p_join_list (serv, serv->favlist);
+		i++;
+
+		/* FIXME this is not going to work and is not needed either. server_free() does the job already. */
+		/* g_slist_free_full (serv->favlist, servlist_favchan_free); */
+	}
+
+	/* This is really only for re-connects when you
+	 * join channels not in the auto-join list.
+	 */
+
+	/* FIXME handle reconnects */
+
+	serv->joindelay_tag = 0;
+	fe_server_event (serv, FE_SE_LOGGEDIN, i);
+
 	return FALSE;
 }
 
diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c
index c763fb71..f6d8af5e 100644
--- a/src/common/proto-irc.c
+++ b/src/common/proto-irc.c
@@ -118,6 +118,7 @@ irc_join (server *serv, char *channel, char *key)
 		tcp_sendf (serv, "JOIN %s\r\n", channel);
 }
 
+#if 0//FIXME remove when finished porting
 static void
 irc_join_list_flush (server *serv, GString *c, GString *k)
 {
@@ -231,6 +232,60 @@ irc_join_list (server *serv, GSList *channels, GSList *keys)
 	}
 
 	irc_join_list_flush (serv, c, k);
+#endif
+
+static void
+irc_join_list_flush (server *serv)
+{
+	/* FIXME implement flushing for too long favorites lists */
+}
+
+static void
+irc_join_list (server *serv, GSList *favorites)
+{
+	int first_item = 1;
+	favchannel *fav;
+	char *chanstr;
+	char *keystr;
+	GString *chanlist = g_string_new (NULL);
+	GString *keylist = g_string_new (NULL);
+	GSList *favlist;
+
+	favlist = favorites;
+
+	while (favlist)
+	{
+		fav = favlist->data;
+
+		if (!first_item)
+		{
+			g_string_append_c (chanlist, ',');				/* add separators but only if it's not the 1st element */
+			g_string_append_c (keylist, ',');
+		}
+
+		g_string_append (chanlist, fav->name);
+
+		if (fav->key)
+		{
+			g_string_append (keylist, fav->key);
+		}
+		else
+		{
+			g_string_append_c (keylist, 'x');				/* 'x' filler for keyless channels */
+		}
+
+		first_item = 0;
+		favlist = favlist->next;
+	}
+
+	chanstr = g_string_free (chanlist, FALSE);				/* convert our strings to char arrays */
+	keystr = g_string_free (keylist, FALSE);
+
+	tcp_sendf (serv, "JOIN %s %s\r\n", chanstr, keystr);	/* send the actual command */
+
+	g_free (chanstr);										/* cleanup */
+	g_free (keystr);
+	g_slist_free (favlist);
 }
 
 static void
diff --git a/src/common/server.c b/src/common/server.c
index 7d48163f..c867e86a 100644
--- a/src/common/server.c
+++ b/src/common/server.c
@@ -2031,7 +2031,7 @@ server_free (server *serv)
 	if (serv->encoding)
 		free (serv->encoding);
 	if (serv->favlist)
-		g_slist_free_full (serv->favlist, g_free);
+		g_slist_free_full (serv->favlist, servlist_favchan_free);
 
 	fe_server_callback (serv);
 
diff --git a/src/common/servlist.c b/src/common/servlist.c
index d5b7dc06..b6e28ac7 100644
--- a/src/common/servlist.c
+++ b/src/common/servlist.c
@@ -617,6 +617,20 @@ servlist_slist_copy_deep (GSList *list, GCopyFunc func, gpointer user_data)
 }
 #endif
 
+favchannel *
+servlist_favchan_copy (favchannel *fav)
+{
+	favchannel *newfav;
+
+	newfav = malloc (sizeof (favchannel));
+	memset (newfav, 0, sizeof (favchannel));
+
+	newfav->name = g_strdup (fav->name);
+	newfav->key = g_strdup (fav->key);		/* g_strdup() can handle NULLs so no need to check it */
+
+	return newfav;
+}
+
 void
 servlist_connect (session *sess, ircnet *net, gboolean join)
 {
@@ -649,9 +663,9 @@ servlist_connect (session *sess, ircnet *net, gboolean join)
 		{
 			if (serv->favlist)
 			{
-				g_slist_free_full (serv->favlist, g_free);
+				g_slist_free_full (serv->favlist, servlist_favchan_free);
 			}
-			serv->favlist = g_slist_copy_deep (net->favchanlist, (GCopyFunc) g_strdup, NULL);
+			serv->favlist = g_slist_copy_deep (net->favchanlist, (GCopyFunc) servlist_favchan_copy, NULL);
 		}
 	}
 
@@ -1031,19 +1045,31 @@ servlist_server_remove_all (ircnet *net)
 }
 
 void
+servlist_command_free (commandentry *entry)
+{
+	g_free (entry->command);
+	g_free (entry);
+}
+
+void
 servlist_command_remove (ircnet *net, commandentry *entry)
 {
-	free (entry->command);
-	free (entry);
+	servlist_command_free (entry);
 	net->commandlist = g_slist_remove (net->commandlist, entry);
 }
 
 void
-servlist_favchan_remove (ircnet *net, favchannel *channel)
+servlist_favchan_free (favchannel *channel)
 {
 	g_free (channel->name);
 	g_free (channel->key);
 	g_free (channel);
+}
+
+void
+servlist_favchan_remove (ircnet *net, favchannel *channel)
+{
+	servlist_favchan_free (channel);
 	net->favchanlist = g_slist_remove (net->favchanlist, channel);
 }
 
@@ -1093,9 +1119,9 @@ servlist_net_remove (ircnet *net)
 		free (net->real);
 	free_and_clear (net->pass);
 	if (net->favchanlist)
-		g_slist_free_full (net->favchanlist, g_free);
+		g_slist_free_full (net->favchanlist, servlist_favchan_free);
 	if (net->commandlist)
-		g_slist_free_full (net->commandlist, g_free);
+		g_slist_free_full (net->commandlist, servlist_command_free);
 	if (net->comment)
 		free (net->comment);
 	if (net->encoding)
diff --git a/src/common/servlist.h b/src/common/servlist.h
index 8558154b..dd88de1d 100644
--- a/src/common/servlist.h
+++ b/src/common/servlist.h
@@ -102,10 +102,15 @@ ircserver *servlist_server_add (ircnet *net, char *name);
 commandentry *servlist_command_add (ircnet *net, char *command);
 favchannel *servlist_favchan_add (ircnet *net, char *channel);
 
+void servlist_command_free (commandentry *entry);
+void servlist_favchan_free (favchannel *channel);
+
 void servlist_server_remove (ircnet *net, ircserver *serv);
 void servlist_command_remove (ircnet *net, commandentry *entry);
 void servlist_favchan_remove (ircnet *net, favchannel *channel);
 
+favchannel *servlist_favchan_copy (favchannel *fav);
+
 gboolean joinlist_is_in_list (server *serv, char *channel);
 
 /* FIXME