changeset 15447:8c81db398f56

This should fix up IRC logins for servers which do not provide an MOTD, which is not required by the spec. All servers MUST send 251 & 255 numerics, so now we key off those. This fixes several IRC bugs in the sourceforge tracker, which should be updated upon release.
author Ethan Blanton <elb@pidgin.im>
date Sun, 28 Jan 2007 17:02:31 +0000
parents 910f4be8fc73
children a75f1459b578
files libpurple/protocols/irc/irc.h libpurple/protocols/irc/msgs.c libpurple/protocols/irc/parse.c
diffstat 3 files changed, 72 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/irc/irc.h	Sun Jan 28 17:01:22 2007 +0000
+++ b/libpurple/protocols/irc/irc.h	Sun Jan 28 17:02:31 2007 +0000
@@ -115,7 +115,6 @@
 void irc_msg_banned(struct irc_conn *irc, const char *name, const char *from, char **args);
 void irc_msg_chanmode(struct irc_conn *irc, const char *name, const char *from, char **args);
 void irc_msg_endwhois(struct irc_conn *irc, const char *name, const char *from, char **args);
-void irc_msg_endmotd(struct irc_conn *irc, const char *name, const char *from, char **args);
 void irc_msg_features(struct irc_conn *irc, const char *name, const char *from, char **args);
 void irc_msg_invite(struct irc_conn *irc, const char *name, const char *from, char **args);
 void irc_msg_inviteonly(struct irc_conn *irc, const char *name, const char *from, char **args);
@@ -123,6 +122,7 @@
 void irc_msg_join(struct irc_conn *irc, const char *name, const char *from, char **args);
 void irc_msg_kick(struct irc_conn *irc, const char *name, const char *from, char **args);
 void irc_msg_list(struct irc_conn *irc, const char *name, const char *from, char **args);
+void irc_msg_luser(struct irc_conn *irc, const char *name, const char *from, char **args);
 void irc_msg_mode(struct irc_conn *irc, const char *name, const char *from, char **args);
 void irc_msg_motd(struct irc_conn *irc, const char *name, const char *from, char **args);
 void irc_msg_names(struct irc_conn *irc, const char *name, const char *from, char **args);
--- a/libpurple/protocols/irc/msgs.c	Sun Jan 28 17:01:22 2007 +0000
+++ b/libpurple/protocols/irc/msgs.c	Sun Jan 28 17:02:31 2007 +0000
@@ -95,6 +95,59 @@
 	}
 }
 
+void irc_msg_luser(struct irc_conn *irc, const char *name, const char *from, char **args)
+{
+	GaimConnection *gc;
+	GaimStatus *status;
+	GaimBlistNode *gnode, *cnode, *bnode;
+
+	if (!args || !args[0] || !args[1])
+		return;
+
+	gc = gaim_account_get_connection(irc->account);
+	if (!gc)
+		return;
+
+	if (!strcmp(name, "251")) {
+		/* 251 is required, so we pluck our nick from here */
+		gaim_connection_set_display_name(gc, args[0]);
+	} else if (!strcmp(name, "255")) {
+		gaim_connection_set_state(gc, GAIM_CONNECTED);
+
+		/* If we're away then set our away message */
+		status = gaim_account_get_active_status(irc->account);
+		if (!gaim_status_get_type(status) != GAIM_STATUS_AVAILABLE) {
+			GaimPluginProtocolInfo *prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl);
+			prpl_info->set_status(irc->account, status);
+		}
+
+		/* this used to be in the core, but it's not now */
+		for (gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) {
+			if(!GAIM_BLIST_NODE_IS_GROUP(gnode))
+				continue;
+			for(cnode = gnode->child; cnode; cnode = cnode->next) {
+				if(!GAIM_BLIST_NODE_IS_CONTACT(cnode))
+					continue;
+				for(bnode = cnode->child; bnode; bnode = bnode->next) {
+					GaimBuddy *b;
+					if(!GAIM_BLIST_NODE_IS_BUDDY(bnode))
+						continue;
+					b = (GaimBuddy *)bnode;
+					if(b->account == gc->account) {
+						struct irc_buddy *ib = g_new0(struct irc_buddy, 1);
+						ib->name = g_strdup(b->name);
+						g_hash_table_insert(irc->buddies, ib->name, ib);
+					}
+				}
+			}
+		}
+
+		irc_blist_timeout(irc);
+		if (!irc->timer)
+			irc->timer = gaim_timeout_add(45000, (GSourceFunc)irc_blist_timeout, (gpointer)irc);
+	}
+}
+
 void irc_msg_away(struct irc_conn *irc, const char *name, const char *from, char **args)
 {
 	GaimConnection *gc;
@@ -465,68 +518,31 @@
 
 void irc_msg_motd(struct irc_conn *irc, const char *name, const char *from, char **args)
 {
-	GaimConnection *gc;
 	char *escaped;
-	if (!strcmp(name, "375")) {
-		gc = gaim_account_get_connection(irc->account);
-		if (gc)
-			gaim_connection_set_display_name(gc, args[0]);
-	}
 
 	if (!irc->motd)
 		irc->motd = g_string_new("");
 
+	if (!strcmp(name, "375")) {
+		if (irc->motd)
+			g_string_free(irc->motd, TRUE);
+		irc->motd = g_string_new("");
+		return;
+	} else if (!strcmp(name, "376")) {
+		/* We no longer have to do anything for ENDMOTD */
+		return;
+	}
+
+	if (!irc->motd) {
+		gaim_debug_error("irc", "IRC server sent MOTD without STARTMOTD\n");
+		return;
+	}
+
 	escaped = g_markup_escape_text(args[1], -1);
 	g_string_append_printf(irc->motd, "%s<br>", escaped);
 	g_free(escaped);
 }
 
-void irc_msg_endmotd(struct irc_conn *irc, const char *name, const char *from, char **args)
-{
-	GaimConnection *gc;
-	GaimStatus *status;
-	GaimBlistNode *gnode, *cnode, *bnode;
-
-	gc = gaim_account_get_connection(irc->account);
-	if (!gc)
-		return;
-
-	gaim_connection_set_state(gc, GAIM_CONNECTED);
-
-	/* If we're away then set our away message */
-	status = gaim_account_get_active_status(irc->account);
-	if (!gaim_status_get_type(status) != GAIM_STATUS_AVAILABLE)
-	{
-		GaimPluginProtocolInfo *prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl);
-		prpl_info->set_status(irc->account, status);
-	}
-
-	/* this used to be in the core, but it's not now */
-	for (gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) {
-		if(!GAIM_BLIST_NODE_IS_GROUP(gnode))
-			continue;
-		for(cnode = gnode->child; cnode; cnode = cnode->next) {
-			if(!GAIM_BLIST_NODE_IS_CONTACT(cnode))
-				continue;
-			for(bnode = cnode->child; bnode; bnode = bnode->next) {
-				GaimBuddy *b;
-				if(!GAIM_BLIST_NODE_IS_BUDDY(bnode))
-					continue;
-				b = (GaimBuddy *)bnode;
-				if(b->account == gc->account) {
-					struct irc_buddy *ib = g_new0(struct irc_buddy, 1);
-					ib->name = g_strdup(b->name);
-					g_hash_table_insert(irc->buddies, ib->name, ib);
-				}
-			}
-		}
-	}
-
-	irc_blist_timeout(irc);
-	if (!irc->timer)
-		irc->timer = gaim_timeout_add(45000, (GSourceFunc)irc_blist_timeout, (gpointer)irc);
-}
-
 void irc_msg_time(struct irc_conn *irc, const char *name, const char *from, char **args)
 {
 	GaimConnection *gc;
--- a/libpurple/protocols/irc/parse.c	Sun Jan 28 17:01:22 2007 +0000
+++ b/libpurple/protocols/irc/parse.c	Sun Jan 28 17:02:31 2007 +0000
@@ -53,6 +53,8 @@
 	void (*cb)(struct irc_conn *irc, const char *name, const char *from, char **args);
 } _irc_msgs[] = {
 	{ "005", "n*", irc_msg_features },	/* Feature list			*/
+	{ "251", "n:", irc_msg_luser },		/* Client & Server count	*/
+	{ "255", "n:", irc_msg_luser },		/* Client & Server count Mk. II	*/
 	{ "301", "nn:", irc_msg_away },		/* User is away			*/
 	{ "303", "n:", irc_msg_ison },		/* ISON reply			*/
 	{ "311", "nnvvv:", irc_msg_whois },	/* Whois user			*/
@@ -73,13 +75,12 @@
 	{ "366", "nc:", irc_msg_names },	/* End of names			*/
 	{ "372", "n:", irc_msg_motd },		/* MOTD				*/
 	{ "375", "n:", irc_msg_motd },		/* Start MOTD			*/
-	{ "376", "n:", irc_msg_endmotd },	/* End of MOTD			*/
+	{ "376", "n:", irc_msg_motd },		/* End of MOTD			*/
 	{ "391", "nv:", irc_msg_time },		/* Time reply			*/
 	{ "401", "nt:", irc_msg_nonick },	/* No such nick/chan		*/
 	{ "403", "nc:", irc_msg_nochan },	/* No such channel		*/
 	{ "404", "nt:", irc_msg_nosend },	/* Cannot send to chan		*/
 	{ "421", "nv:", irc_msg_unknown },	/* Unknown command		*/
-	{ "422", "nv:", irc_msg_endmotd },	/* No MOTD available		*/
 	{ "432", "vn:", irc_msg_badnick },	/* Erroneous nickname		*/
 	{ "433", "vn:", irc_msg_nickused },	/* Nickname already in use	*/
 	{ "437", "nc:", irc_msg_unavailable },  /* Nick/channel is unavailable */