changeset 10941:cef48e318125

[gaim-migrate @ 12731] sick of having my tree be so far out of sync...here's all my jabber stuff most notable is the "iChat" buddy icon support committer: Tailor Script <tailor@pidgin.im>
author Nathan Walp <nwalp@pidgin.im>
date Thu, 26 May 2005 04:13:06 +0000
parents 999555fbbbd9
children 77cb56ff14e1
files src/protocols/jabber/buddy.c src/protocols/jabber/chat.c src/protocols/jabber/chat.h src/protocols/jabber/iq.c src/protocols/jabber/jabber.c src/protocols/jabber/jabber.h src/protocols/jabber/presence.c src/protocols/jabber/roster.c
diffstat 8 files changed, 140 insertions(+), 73 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/jabber/buddy.c	Thu May 26 03:54:25 2005 +0000
+++ b/src/protocols/jabber/buddy.c	Thu May 26 04:13:06 2005 +0000
@@ -384,13 +384,14 @@
 			gsize avatar_len;
 
 			if(avatar_file && g_file_get_contents(avatar_file, (gchar **)&avatar_data, &avatar_len, &error)) {
-				xmlnode *photo;
+				xmlnode *photo, *binval;
 				unsigned char *enc;
 				int i;
 				unsigned char hashval[20];
 				char *p, hash[41];
 
 				photo = xmlnode_new_child(vc_node, "PHOTO");
+				binval = xmlnode_new_child(photo, "BINVAL");
 				enc = gaim_base64_encode(avatar_data, avatar_len);
 
 				gaim_cipher_digest_region("sha1", (guint8 *)avatar_data,
@@ -402,7 +403,7 @@
 					snprintf(p, 3, "%02x", hashval[i]);
 				js->avatar_hash = g_strdup(hash);
 
-				xmlnode_insert_data(photo, enc, -1);
+				xmlnode_insert_data(binval, enc, -1);
 				g_free(enc);
 				g_free(avatar_data);
 			} else if (error != NULL) {
@@ -804,30 +805,36 @@
 						_("Description"), text);
 			} else if(!strcmp(child->name, "PHOTO") ||
 					!strcmp(child->name, "LOGO")) {
-				int size, i;
-				unsigned char hashval[20];
-				char *data, *p, hash[41];
-				gboolean photo = (strcmp(child->name, "PHOTO") == 0);
+				char *bintext = NULL;
+				xmlnode *binval;
+				if((binval = xmlnode_get_child(child, "BINVAL")) &&
+						(bintext = xmlnode_get_data(binval))) {
+					int size, i;
+					unsigned char hashval[20];
+					char *data, *p, hash[41];
+					gboolean photo = (strcmp(child->name, "PHOTO") == 0);
 
-				gaim_base64_decode(text, &data, &size);
+					gaim_base64_decode(text, &data, &size);
 
-				imgids = g_slist_prepend(imgids, GINT_TO_POINTER(gaim_imgstore_add(data, size, "logo.png")));
-				g_string_append_printf(info_text,
-						"<b>%s:</b> <img id='%d'><br/>",
-						photo ? _("Photo") : _("Logo"),
-						GPOINTER_TO_INT(imgids->data));
+					imgids = g_slist_prepend(imgids, GINT_TO_POINTER(gaim_imgstore_add(data, size, "logo.png")));
+					g_string_append_printf(info_text,
+							"<b>%s:</b> <img id='%d'><br/>",
+							photo ? _("Photo") : _("Logo"),
+							GPOINTER_TO_INT(imgids->data));
 
-				gaim_buddy_icons_set_for_user(js->gc->account, bare_jid,
-						data, size);
+					gaim_buddy_icons_set_for_user(js->gc->account, bare_jid,
+							data, size);
 
-				gaim_cipher_digest_region("sha1", (guint8 *)data, size,
-										  sizeof(hashval), hashval, NULL);
-				p = hash;
-				for(i=0; i<20; i++, p+=2)
-					snprintf(p, 3, "%02x", hashval[i]);
-				gaim_blist_node_set_string((GaimBlistNode*)b, "avatar_hash", hash);
+					gaim_cipher_digest_region("sha1", (guint8 *)data, size,
+							sizeof(hashval), hashval, NULL);
+					p = hash;
+					for(i=0; i<20; i++, p+=2)
+						snprintf(p, 3, "%02x", hashval[i]);
+					gaim_blist_node_set_string((GaimBlistNode*)b, "avatar_hash", hash);
 
-				g_free(data);
+					g_free(data);
+					g_free(bintext);
+				}
 			}
 			g_free(text);
 		}
--- a/src/protocols/jabber/chat.c	Thu May 26 03:54:25 2005 +0000
+++ b/src/protocols/jabber/chat.c	Thu May 26 04:13:06 2005 +0000
@@ -883,5 +883,50 @@
 	return TRUE;
 }
 
+static void jabber_chat_disco_traffic_cb(JabberStream *js, xmlnode *packet, gpointer data)
+{
+	JabberChat *chat;
+	xmlnode *query, *x, *error;
+	int id = GPOINTER_TO_INT(data);
+
+	if(!(chat = jabber_chat_find_by_id(js, id)))
+		return;
+
+	if((error = xmlnode_get_child(packet, "error"))) {
+		/* defaults, in case the conference server doesn't
+		 * support this request */
+		chat->xhtml = TRUE;
+		return;
+	}
+
+	if(!(query = xmlnode_get_child(packet, "query")))
+		return;
+
+	for(x = xmlnode_get_child(query, "feature"); x; x = xmlnode_get_next_twin(x)) {
+		const char *var = xmlnode_get_attrib(x, "var");
+
+		if(var && !strcmp(var, "http://jabber.org/protocol/xhtml-im")) {
+			chat->xhtml = TRUE;
+		}
+	}
+}
+
+void jabber_chat_disco_traffic(JabberChat *chat)
+{
+	JabberIq *iq;
+	xmlnode *query;
+
+	iq = jabber_iq_new_query(chat->js, JABBER_IQ_GET,
+			"http://jabber.org/protocol/disco#info");
+
+	query = xmlnode_get_child(iq->node, "query");
+
+	xmlnode_set_attrib(query, "node", "http://jabber.org/protocol/muc#traffic");
+
+	jabber_iq_set_callback(iq, jabber_chat_disco_traffic_cb, GINT_TO_POINTER(chat->id));
+
+	jabber_iq_send(iq);
+}
 
 
+
--- a/src/protocols/jabber/chat.h	Thu May 26 03:54:25 2005 +0000
+++ b/src/protocols/jabber/chat.h	Thu May 26 04:13:06 2005 +0000
@@ -83,5 +83,7 @@
 GaimRoomlist *jabber_roomlist_get_list(GaimConnection *gc);
 void jabber_roomlist_cancel(GaimRoomlist *list);
 
+void jabber_chat_disco_traffic(JabberChat *chat);
+
 
 #endif /* _GAIM_JABBER_CHAT_H_ */
--- a/src/protocols/jabber/iq.c	Thu May 26 03:54:25 2005 +0000
+++ b/src/protocols/jabber/iq.c	Thu May 26 04:13:06 2005 +0000
@@ -21,6 +21,7 @@
 #include "internal.h"
 #include "debug.h"
 #include "prefs.h"
+#include "util.h"
 
 #include "buddy.h"
 #include "disco.h"
@@ -179,6 +180,7 @@
 	id = xmlnode_get_attrib(packet, "id");
 
 	if(type && !strcmp(type, "get")) {
+		char *utf8;
 
 		iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "jabber:iq:time");
 		jabber_iq_set_id(iq, id);
@@ -188,10 +190,18 @@
 
 		strftime(buf, sizeof(buf), "%Y%m%dT%T", now);
 		xmlnode_insert_data(xmlnode_new_child(query, "utc"), buf, -1);
+
 		strftime(buf, sizeof(buf), "%Z", now);
-		xmlnode_insert_data(xmlnode_new_child(query, "tz"), buf, -1);
+		if((utf8 = gaim_utf8_try_convert(buf))) {
+			xmlnode_insert_data(xmlnode_new_child(query, "tz"), utf8, -1);
+			g_free(utf8);
+		}
+
 		strftime(buf, sizeof(buf), "%d %b %Y %T", now);
-		xmlnode_insert_data(xmlnode_new_child(query, "display"), buf, -1);
+		if((utf8 = gaim_utf8_try_convert(buf))) {
+			xmlnode_insert_data(xmlnode_new_child(query, "display"), utf8, -1);
+			g_free(utf8);
+		}
 
 		jabber_iq_send(iq);
 	}
@@ -202,11 +212,12 @@
 	JabberIq *iq;
 	const char *type, *from, *id;
 	xmlnode *query;
+	char *os = NULL;
 
 	type = xmlnode_get_attrib(packet, "type");
 
 	if(type && !strcmp(type, "get")) {
-#if 0
+
 		if(!gaim_prefs_get_bool("/plugins/prpl/jabber/hide_os")) {
 			struct utsname osinfo;
 
@@ -214,7 +225,7 @@
 			os = g_strdup_printf("%s %s %s", osinfo.sysname, osinfo.release,
 					osinfo.machine);
 		}
-#endif
+
 		from = xmlnode_get_attrib(packet, "from");
 		id = xmlnode_get_attrib(packet, "id");
 
@@ -226,12 +237,11 @@
 
 		xmlnode_insert_data(xmlnode_new_child(query, "name"), PACKAGE, -1);
 		xmlnode_insert_data(xmlnode_new_child(query, "version"), VERSION, -1);
-#if 0
 		if(os) {
 			xmlnode_insert_data(xmlnode_new_child(query, "os"), os, -1);
 			g_free(os);
 		}
-#endif
+
 		jabber_iq_send(iq);
 	}
 }
--- a/src/protocols/jabber/jabber.c	Thu May 26 03:54:25 2005 +0000
+++ b/src/protocols/jabber/jabber.c	Thu May 26 04:13:06 2005 +0000
@@ -826,11 +826,11 @@
 			jabber_stream_init(js);
 			break;
 		case JABBER_STREAM_CONNECTED:
-			gaim_connection_set_state(js->gc, GAIM_CONNECTED);
 			jabber_roster_request(js);
 			gpresence = gaim_account_get_presence(js->gc->account);
 			status = gaim_presence_get_active_status(gpresence);
 			jabber_presence_send(js->gc->account, status);
+			gaim_connection_set_state(js->gc, GAIM_CONNECTED);
 			jabber_disco_items_server(js);
 			break;
 	}
@@ -947,6 +947,7 @@
 				stripped = gaim_markup_strip_html(jbr->status);
 				text = g_markup_escape_text(stripped, -1);
 				g_free(stripped);
+				/* XXX: need some nl to br love here */
 			}
 
 			g_string_append_printf(ret, "\n<b>%s:</b> %s%s%s",
@@ -1618,7 +1619,10 @@
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
 			option);
 
-	option = gaim_account_option_bool_new(_("Force old SSL"), "old_ssl", FALSE);
+	option = gaim_account_option_bool_new(_("Require TLS"), "require_tls", TRUE);
+	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
+
+	option = gaim_account_option_bool_new(_("Force old (port 5223) SSL"), "old_ssl", FALSE);
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
 			option);
 
--- a/src/protocols/jabber/jabber.h	Thu May 26 03:54:25 2005 +0000
+++ b/src/protocols/jabber/jabber.h	Thu May 26 04:13:06 2005 +0000
@@ -97,6 +97,7 @@
 	gboolean registration;
 
 	char *avatar_hash;
+	GSList *pending_avatar_requests;
 } JabberStream;
 
 void jabber_process_packet(JabberStream *js, xmlnode *packet);
--- a/src/protocols/jabber/presence.c	Thu May 26 03:54:25 2005 +0000
+++ b/src/protocols/jabber/presence.c	Thu May 26 04:13:06 2005 +0000
@@ -202,8 +202,9 @@
 
 static void jabber_vcard_parse_avatar(JabberStream *js, xmlnode *packet, gpointer blah)
 {
+	JabberBuddy *jb = NULL;
 	GaimBuddy *b = NULL;
-	xmlnode *vcard, *photo;
+	xmlnode *vcard, *photo, *binval;
 	char *text, *data;
 	int size;
 	const char *from = xmlnode_get_attrib(packet, "from");
@@ -211,26 +212,31 @@
 	if(!from)
 		return;
 
+	jb = jabber_buddy_find(js, from, TRUE);
+
+	js->pending_avatar_requests = g_slist_remove(js->pending_avatar_requests, jb);
+
 	if((vcard = xmlnode_get_child(packet, "vCard")) ||
 			(vcard = xmlnode_get_child_with_namespace(packet, "query", "vcard-temp"))) {
-		if((photo = xmlnode_get_child(vcard, "PHOTO"))) {
-			if((text = xmlnode_get_data(photo))) {
-				gaim_base64_decode(text, &data, &size);
+		if((photo = xmlnode_get_child(vcard, "PHOTO")) &&
+				(binval = xmlnode_get_child(photo, "BINVAL")) &&
+				(text = xmlnode_get_data(binval))) {
+			gaim_base64_decode(text, &data, &size);
 
-				gaim_buddy_icons_set_for_user(js->gc->account, from, data, size);
-				if((b = gaim_find_buddy(js->gc->account, from))) {
-					unsigned char hashval[20];
-					char hash[41], *p;
-					int i;
+			gaim_buddy_icons_set_for_user(js->gc->account, from, data, size);
+			if((b = gaim_find_buddy(js->gc->account, from))) {
+				unsigned char hashval[20];
+				char hash[41], *p;
+				int i;
 
-					gaim_cipher_digest_region("sha1", (guint8 *)data, size,
-											  sizeof(hashval), hashval, NULL);
- 					p = hash;
-					for(i=0; i<20; i++, p+=2)
-						snprintf(p, 3, "%02x", hashval[i]);
-					gaim_blist_node_set_string((GaimBlistNode*)b, "avatar_hash", hash);
-				}
+				gaim_cipher_digest_region("sha1", (guint8 *)data, size,
+						sizeof(hashval), hashval, NULL);
+				p = hash;
+				for(i=0; i<20; i++, p+=2)
+					snprintf(p, 3, "%02x", hashval[i]);
+				gaim_blist_node_set_string((GaimBlistNode*)b, "avatar_hash", hash);
 			}
+			g_free(text);
 		}
 	}
 }
@@ -464,28 +470,7 @@
 				chat->conv = serv_got_joined_chat(js->gc, chat->id, room_jid);
 				gaim_conv_chat_set_nick(GAIM_CONV_CHAT(chat->conv), chat->handle);
 
-				/* <iq to='room@server'
-				   type='get'>
-				   <query xmlns='http://jabber.org/protocol/disco#info'
-				   node='http://jabber.org/protocol/muc#traffic'/>
-				   </iq>
-				   */
-				/* expected response format:
-				   <iq from='room@server'
-				   type='get'>
-				   <query xmlns='http://jabber.org/protocol/disco#info'
-				   node='http://jabber.org/protocol/muc#traffic'>
-				   <feature var='http://jabber.org/protocol/xhtml-im'/>
-				   <feature var='jabber:x:roster/'/>
-				   </query>
-				   </iq>
-				   */
-				/*
-				 * XXX: i'm not sure if we turn off XHTML unless we get
-				 * xhtml back in this, or if we turn it off only if we
-				 * get a response, and it's not there.  Ask stpeter to
-				 * clarify.
-				 */
+				jabber_chat_disco_traffic(chat);
 			}
 
 			jabber_buddy_track_resource(jb, jid->resource, priority, state,
@@ -529,13 +514,23 @@
 				JabberIq *iq;
 				xmlnode *vcard;
 
-				iq = jabber_iq_new(js, JABBER_IQ_GET);
-				xmlnode_set_attrib(iq->node, "to", buddy_name);
-				vcard = xmlnode_new_child(iq->node, "vCard");
-				xmlnode_set_attrib(vcard, "xmlns", "vcard-temp");
+				/* XXX this is a crappy way of trying to prevent
+				 * someone from spamming us with presence packets
+				 * and causing us to DoS ourselves...what we really
+				 * need is a queue system that can throttle itself,
+				 * but i'm too tired to write that right now */
+				if(!g_slist_find(js->pending_avatar_requests, jb)) {
+
+					js->pending_avatar_requests = g_slist_prepend(js->pending_avatar_requests, jb);
 
-				jabber_iq_set_callback(iq, jabber_vcard_parse_avatar, NULL);
-				jabber_iq_send(iq);
+					iq = jabber_iq_new(js, JABBER_IQ_GET);
+					xmlnode_set_attrib(iq->node, "to", buddy_name);
+					vcard = xmlnode_new_child(iq->node, "vCard");
+					xmlnode_set_attrib(vcard, "xmlns", "vcard-temp");
+
+					jabber_iq_set_callback(iq, jabber_vcard_parse_avatar, NULL);
+					jabber_iq_send(iq);
+				}
 			}
 		}
 
--- a/src/protocols/jabber/roster.c	Thu May 26 03:54:25 2005 +0000
+++ b/src/protocols/jabber/roster.c	Thu May 26 04:13:06 2005 +0000
@@ -170,6 +170,9 @@
 				jb->subscription = JABBER_SUB_BOTH;
 			else if(!strcmp(subscription, "remove"))
 				jb->subscription = JABBER_SUB_REMOVE;
+			/* XXX: if subscription is now "from" or "none" we need to
+			 * fake a signoff, since we won't get any presence from them
+			 * anymore */
 		}
 
 		if(ask && !strcmp(ask, "subscribe"))