changeset 8043:9a6df4d567e0

[gaim-migrate @ 8727] I think I can sneak this stuff in here before we release committer: Tailor Script <tailor@pidgin.im>
author Nathan Walp <nwalp@pidgin.im>
date Sat, 10 Jan 2004 01:48:24 +0000
parents 7fa6ddec6e30
children 34b086e2619d
files src/protocols/jabber/chat.c src/protocols/jabber/iq.c src/protocols/jabber/jabber.c src/protocols/jabber/jabber.h src/protocols/jabber/jutil.c src/protocols/jabber/jutil.h src/protocols/jabber/message.c src/protocols/jabber/presence.c
diffstat 8 files changed, 154 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/jabber/chat.c	Fri Jan 09 16:58:33 2004 +0000
+++ b/src/protocols/jabber/chat.c	Sat Jan 10 01:48:24 2004 +0000
@@ -41,12 +41,10 @@
 	pce->identifier = "room";
 	m = g_list_append(m, pce);
 
-	/* we're gonna default to a conference server I know is true, until
-	 * I can figure out how to disco for a chat server */
 	pce = g_new0(struct proto_chat_entry, 1);
 	pce->label = _("_Server:");
 	pce->identifier = "server";
-	pce->def = "conference.jabber.org";
+	pce->def = js->chat_servers ? js->chat_servers->data : "conference.jabber.org";
 	m = g_list_append(m, pce);
 
 	pce = g_new0(struct proto_chat_entry, 1);
--- a/src/protocols/jabber/iq.c	Fri Jan 09 16:58:33 2004 +0000
+++ b/src/protocols/jabber/iq.c	Sat Jan 10 01:48:24 2004 +0000
@@ -278,6 +278,7 @@
 		SUPPORT_FEATURE("http://jabber.org/protocol/si")
 		SUPPORT_FEATURE("http://jabber.org/protocol/si/profile/file-transfer")
 		*/
+		SUPPORT_FEATURE("http://jabber.org/protocol/xhtml-im")
 
 		jabber_iq_send(iq);
 	} else if(!strcmp(type, "result")) {
@@ -294,24 +295,32 @@
 			jbr = jabber_buddy_find_resource(jb, jid->resource);
 		jabber_id_free(jid);
 
-		if(!jbr)
-			return;
-
 		for(child = query->child; child; child = child->next) {
 			if(child->type != NODE_TYPE_TAG)
 				continue;
 
-			if(!strcmp(child->name, "feature")) {
+			if(!strcmp(child->name, "identity")) {
+				const char *category = xmlnode_get_attrib(child, "category");
+				const char *type = xmlnode_get_attrib(child, "type");
+				if(!category || !type)
+					continue;
+
+				/* we found a groupchat or MUC server, add it to the list */
+				/* XXX: actually check for protocol/muc or gc-1.0 support */
+				if(!strcmp(category, "conference") && !strcmp(type, "text"))
+					js->chat_servers = g_list_append(js->chat_servers, g_strdup(from));
+
+			} else if(!strcmp(child->name, "feature")) {
 				const char *var = xmlnode_get_attrib(child, "var");
 				if(!var)
 					continue;
 
-				if(!strcmp(var, "http://jabber.org/protocol/si"))
+				if(jbr && !strcmp(var, "http://jabber.org/protocol/si"))
 					jbr->capabilities |= JABBER_CAP_SI;
-				else if(!strcmp(var,
+				else if(jbr && !strcmp(var,
 							"http://jabber.org/protocol/si/profile/file-transfer"))
 					jbr->capabilities |= JABBER_CAP_SI_FILE_XFER;
-				else if(!strcmp(var, "http://jabber.org/protocol/bytestreams"))
+				else if(jbr && !strcmp(var, "http://jabber.org/protocol/bytestreams"))
 					jbr->capabilities |= JABBER_CAP_BYTESTREAMS;
 			}
 		}
@@ -333,6 +342,58 @@
 	}
 }
 
+static void
+jabber_iq_disco_server_result_cb(JabberStream *js, xmlnode *packet, gpointer data)
+{
+	xmlnode *query, *child;
+	const char *from = xmlnode_get_attrib(packet, "from");
+	const char *type = xmlnode_get_attrib(packet, "type");
+
+	if(!from || !type)
+		return;
+
+	if(strcmp(from, js->user->domain))
+		return;
+
+	if(strcmp(type, "result"))
+		return;
+
+	while(js->chat_servers) {
+		g_free(js->chat_servers->data);
+		js->chat_servers = g_list_delete_link(js->chat_servers, js->chat_servers);
+	}
+
+	query = xmlnode_get_child(packet, "query");
+
+	for(child = query->child; child; child = child->next) {
+		JabberIq *iq;
+		const char *jid;
+
+		if(child->type != NODE_TYPE_TAG)
+			continue;
+		if(strcmp(child->name, "item"))
+			continue;
+		if(!(jid = xmlnode_get_attrib(child, "jid")))
+			continue;
+
+		iq = jabber_iq_new_query(js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#info");
+		xmlnode_set_attrib(iq->node, "to", jid);
+		jabber_iq_send(iq);
+	}
+}
+
+void jabber_iq_disco_server(JabberStream *js)
+{
+	JabberIq *iq = jabber_iq_new_query(js, JABBER_IQ_GET,
+			"http://jabber.org/protocol/disco#items");
+
+	xmlnode_set_attrib(iq->node, "to", js->user->domain);
+
+	jabber_iq_set_callback(iq, jabber_iq_disco_server_result_cb, NULL);
+	jabber_iq_send(iq);
+}
+
+
 void jabber_iq_parse(JabberStream *js, xmlnode *packet)
 {
 	JabberCallbackData *jcd;
@@ -341,50 +402,51 @@
 	const char *type, *id;
 
 	query = xmlnode_get_child(packet, "query");
-
-	if(query) {
-
-		xmlns = xmlnode_get_attrib(query, "xmlns");
-
-		if(!xmlns)
-			return;
+	type = xmlnode_get_attrib(packet, "type");
 
-		if(!strcmp(xmlns, "jabber:iq:roster")) {
-			jabber_roster_parse(js, packet);
-			return;
-		} else if(!strcmp(xmlns, "jabber:iq:last")) {
-			jabber_iq_handle_last(js, packet);
-			return;
-		} else if(!strcmp(xmlns, "jabber:iq:time")) {
-			jabber_iq_handle_time(js, packet);
-			return;
-		} else if(!strcmp(xmlns, "jabber:iq:version")) {
-			jabber_iq_handle_version(js, packet);
-			return;
-		} else if(!strcmp(xmlns, "jabber:iq:register")) {
-			jabber_register_parse(js, packet);
-			return;
-		} else if(!strcmp(xmlns, "jabber:iq:oob")) {
-			jabber_oob_parse(js, packet);
-			return;
-		} else if(!strcmp(xmlns, "http://jabber.org/protocol/disco#info")) {
-			jabber_disco_info_parse(js, packet);
-			return;
-		} else if(!strcmp(xmlns, "http://jabber.org/protocol/disco#items")) {
-			jabber_disco_items_parse(js, packet);
-			return;
+	if(type && query && (xmlns = xmlnode_get_attrib(query, "xmlns"))) {
+		if(!strcmp(type, "set")) {
+			if(!strcmp(xmlns, "jabber:iq:roster")) {
+				jabber_roster_parse(js, packet);
+				return;
+			} else if(!strcmp(xmlns, "jabber:iq:oob")) {
+				jabber_oob_parse(js, packet);
+				return;
+			}
+		} else if(!strcmp(type, "get")) {
+			if(!strcmp(xmlns, "jabber:iq:last")) {
+				jabber_iq_handle_last(js, packet);
+				return;
+			} else if(!strcmp(xmlns, "jabber:iq:time")) {
+				jabber_iq_handle_time(js, packet);
+				return;
+			} else if(!strcmp(xmlns, "jabber:iq:version")) {
+				jabber_iq_handle_version(js, packet);
+				return;
+			} else if(!strcmp(xmlns, "http://jabber.org/protocol/disco#info")) {
+				jabber_disco_info_parse(js, packet);
+				return;
+			} else if(!strcmp(xmlns, "http://jabber.org/protocol/disco#items")) {
+				jabber_disco_items_parse(js, packet);
+				return;
+			}
+		} else if(!strcmp(type, "result")) {
+			if(!strcmp(xmlns, "jabber:iq:roster")) {
+				jabber_roster_parse(js, packet);
+				return;
+			} else if(!strcmp(xmlns, "jabber:iq:register")) {
+				jabber_register_parse(js, packet);
+				return;
+			} else if(!strcmp(xmlns, "http://jabber.org/protocol/disco#info")) {
+				jabber_disco_info_parse(js, packet);
+				return;
+			}
 		}
-	/*
-	} else if(xmlnode_get_child(packet, "si")) {
-		jabber_si_parse(js, packet);
-		return;
-	*/
 	}
 
 	/* If we got here, no pre-defined handlers got it, lets see if a special
 	 * callback got registered */
 
-	type = xmlnode_get_attrib(packet, "type");
 	id = xmlnode_get_attrib(packet, "id");
 
 	if(type && (!strcmp(type, "result") || !strcmp(type, "error")) && id
--- a/src/protocols/jabber/jabber.c	Fri Jan 09 16:58:33 2004 +0000
+++ b/src/protocols/jabber/jabber.c	Sat Jan 10 01:48:24 2004 +0000
@@ -380,6 +380,7 @@
 			g_free, (GDestroyNotify)jabber_buddy_free);
 	js->chats = g_hash_table_new_full(g_str_hash, g_str_equal,
 			g_free, NULL);
+	js->chat_servers = g_list_append(NULL, g_strdup("conference.jabber.org"));
 	js->user = jabber_id_new(gaim_account_get_username(account));
 	js->next_id = g_random_int();
 
@@ -777,6 +778,10 @@
 		g_hash_table_destroy(js->buddies);
 	if(js->chats)
 		g_hash_table_destroy(js->chats);
+	while(js->chat_servers) {
+		g_free(js->chat_servers->data);
+		js->chat_servers = g_list_delete_link(js->chat_servers, js->chat_servers);
+	}
 	if(js->stream_id)
 		g_free(js->stream_id);
 	if(js->user)
@@ -784,15 +789,6 @@
 	g_free(js);
 }
 
-static void jabber_server_probe(JabberStream *js)
-{
-	JabberIq *iq = jabber_iq_new_query(js, JABBER_IQ_GET,
-			"http://jabber.org/protocol/disco#items");
-
-	xmlnode_set_attrib(iq->node, "to", js->user->domain);
-	jabber_iq_send(iq);
-}
-
 void jabber_stream_set_state(JabberStream *js, JabberStreamState state)
 {
 	js->state = state;
@@ -828,7 +824,7 @@
 			gaim_connection_set_state(js->gc, GAIM_CONNECTED);
 			jabber_roster_request(js);
 			jabber_presence_send(js->gc, js->gc->away_state, js->gc->away);
-			jabber_server_probe(js);
+			jabber_iq_disco_server(js);
 			serv_finish_login(js->gc);
 			break;
 	}
--- a/src/protocols/jabber/jabber.h	Fri Jan 09 16:58:33 2004 +0000
+++ b/src/protocols/jabber/jabber.h	Sat Jan 10 01:48:24 2004 +0000
@@ -64,6 +64,7 @@
 	gboolean roster_parsed;
 
 	GHashTable *chats;
+	GList *chat_servers;
 
 	GHashTable *callbacks;
 	int next_id;
@@ -91,4 +92,6 @@
 
 char *jabber_get_next_id(JabberStream *js);
 
+void jabber_iq_disco_server(JabberStream *js);
+
 #endif /* _GAIM_JABBER_H_ */
--- a/src/protocols/jabber/jutil.c	Fri Jan 09 16:58:33 2004 +0000
+++ b/src/protocols/jabber/jutil.c	Sat Jan 10 01:48:24 2004 +0000
@@ -20,6 +20,7 @@
  */
 #include "internal.h"
 #include "server.h"
+#include "util.h"
 
 #include "chat.h"
 #include "presence.h"
@@ -300,3 +301,21 @@
 	return buf;
 }
 
+GaimConversation *
+jabber_find_unnormalized_conv(const char *name, GaimAccount *account)
+{
+	GaimConversation *c = NULL;
+	GList *cnv;
+
+	g_return_val_if_fail(name != NULL, NULL);
+
+	for(cnv = gaim_get_conversations(); cnv; cnv = cnv->next) {
+		c = (GaimConversation*)cnv->data;
+		if(gaim_conversation_get_type(c) == GAIM_CONV_IM &&
+				!gaim_utf8_strcasecmp(name, gaim_conversation_get_name(c)) &&
+				account == gaim_conversation_get_account(c))
+			return c;
+	}
+
+	return NULL;
+}
--- a/src/protocols/jabber/jutil.h	Fri Jan 09 16:58:33 2004 +0000
+++ b/src/protocols/jabber/jutil.h	Sat Jan 10 01:48:24 2004 +0000
@@ -23,6 +23,7 @@
 #define _GAIM_JABBER_JUTIL_H_
 
 #include "account.h"
+#include "conversation.h"
 
 
 typedef struct _JabberID {
@@ -46,4 +47,6 @@
 gboolean jabber_nameprep_validate(const char *);
 gboolean jabber_resourceprep_validate(const char *);
 
+GaimConversation *jabber_find_unnormalized_conv(const char *name, GaimAccount *account);
+
 #endif /* _GAIM_JABBER_JUTIL_H_ */
--- a/src/protocols/jabber/message.c	Fri Jan 09 16:58:33 2004 +0000
+++ b/src/protocols/jabber/message.c	Sat Jan 10 01:48:24 2004 +0000
@@ -52,25 +52,6 @@
 	g_free(jm);
 }
 
-static GaimConversation *
-find_unnormalized_im(const char *name, GaimAccount *account)
-{
-	GaimConversation *c = NULL;
-	GList *cnv;
-
-	g_return_val_if_fail(name != NULL, NULL);
-
-	for(cnv = gaim_get_conversations(); cnv; cnv = cnv->next) {
-		c = (GaimConversation*)cnv->data;
-		if(gaim_conversation_get_type(c) == GAIM_CONV_IM &&
-				!gaim_utf8_strcasecmp(name, gaim_conversation_get_name(c)) &&
-				account == gaim_conversation_get_account(c))
-			return c;
-	}
-
-	return NULL;
-}
-
 static void handle_chat(JabberMessage *jm)
 {
 	JabberID *jid = jabber_id_new(jm->from);
@@ -85,13 +66,13 @@
 	jb = jabber_buddy_find(jm->js, jm->from, TRUE);
 	jbr = jabber_buddy_find_resource(jb, jid->resource);
 
-	if(find_unnormalized_im(jm->from, jm->js->gc->account)) {
+	if(jabber_find_unnormalized_conv(jm->from, jm->js->gc->account)) {
 		from = g_strdup(jm->from);
 	} else  if(jid->node) {
 		GaimConversation *conv;
 
 		from = g_strdup_printf("%s@%s", jid->node, jid->domain);
-		conv = find_unnormalized_im(from, jm->js->gc->account);
+		conv = jabber_find_unnormalized_conv(from, jm->js->gc->account);
 		if(conv)
 			gaim_conversation_set_name(conv, jm->from);
 		g_free(from);
@@ -491,6 +472,9 @@
 	js = gc->proto_data;
 	chat = jabber_chat_find_by_id(js, id);
 
+	if(!chat)
+		return 0;
+
 	if(!strcmp(msg, "/configure") || !strcmp(msg, "/config")) {
 		jabber_chat_request_room_configure(chat);
 		return 1;
@@ -507,8 +491,6 @@
 	} else if(!strncmp(msg, "/part", 5)) {
 		jabber_chat_part(chat, strlen(msg) > 6 ? msg+6 : NULL);
 		return 1;
-	} else if(!strncmp(msg, "/ban", 4)) {
-	} else if(!strncmp(msg, "/kick", 5)) {
 	}
 
 	jm = g_new0(JabberMessage, 1);
--- a/src/protocols/jabber/presence.c	Fri Jan 09 16:58:33 2004 +0000
+++ b/src/protocols/jabber/presence.c	Sat Jan 10 01:48:24 2004 +0000
@@ -153,9 +153,11 @@
 	xmlnode *y;
 	gboolean muc = FALSE;
 
-	jb = jabber_buddy_find(js, from, TRUE);
 
-	if(!jb)
+	if(!(jb = jabber_buddy_find(js, from, TRUE)))
+		return;
+
+	if(!(jid = jabber_id_new(from)))
 		return;
 
 	if(jb->error_msg) {
@@ -188,9 +190,11 @@
 				_("Authorize"), G_CALLBACK(authorize_add_cb),
 				_("Deny"), G_CALLBACK(deny_add_cb));
 		g_free(msg);
+		jabber_id_free(jid);
 		return;
 	} else if(type && !strcmp(type, "subscribed")) {
 		/* we've been allowed to see their presence, but we don't care */
+		jabber_id_free(jid);
 		return;
 	} else {
 		if((y = xmlnode_get_child(packet, "show"))) {
@@ -212,8 +216,6 @@
 		}
 	}
 
-	if(!(jid = jabber_id_new(from)))
-		return;
 
 	for(y = packet->child; y; y = y->next) {
 		if(y->type != NODE_TYPE_TAG)
@@ -377,7 +379,12 @@
 		if(state == JABBER_STATE_ERROR ||
 				(type && (!strcmp(type, "unavailable") ||
 						  !strcmp(type, "unsubscribed")))) {
+			GaimConversation *conv;
+
 			jabber_buddy_remove_resource(jb, jid->resource);
+			if((conv = jabber_find_unnormalized_conv(from, js->gc->account)))
+				gaim_conversation_set_name(conv, buddy_name);
+
 		} else {
 			jabber_buddy_track_resource(jb, jid->resource, priority, state,
 					status);