adium.1-3: acba16d8: disapproval of revision '18b0a096bd6f210...

zacw at adiumx.com zacw at adiumx.com
Thu Jul 9 16:51:41 EDT 2009


-----------------------------------------------------------------
Revision: acba16d85594300e11e7c7d3eaa03deb2463e5db
Ancestor: 18b0a096bd6f21011f16c7b08c1aac016d2c0fff
Author: zacw at adiumx.com
Date: 2009-07-09T20:46:41
Branch: im.pidgin.adium.1-3
URL: http://d.pidgin.im/viewmtn/revision/info/acba16d85594300e11e7c7d3eaa03deb2463e5db

Modified files:
        libpurple/protocols/yahoo/yahoo.c
        libpurple/protocols/yahoo/yahoo.h
        libpurple/protocols/yahoo/yahoo_picture.c
        libpurple/protocols/yahoo/yahoo_picture.h libpurple/util.c

ChangeLog: 

disapproval of revision '18b0a096bd6f21011f16c7b08c1aac016d2c0fff'
-------------- next part --------------
============================================================
--- libpurple/protocols/yahoo/yahoo.c	d024cadc2b6baa33e9f462384dffac20ad308cf8
+++ libpurple/protocols/yahoo/yahoo.c	c2559a05aa07ddab2c2f637989edc7f5061dbd81
@@ -580,6 +580,9 @@ static void yahoo_process_list(PurpleCon
 			else
 				g_string_append(yd->tmp_serv_ilist, pair->value);
 			break;
+		case 89:
+			yd->profiles = g_strsplit(pair->value, ",", -1);
+			break;
 		case 59: /* cookies, yum */
 			yahoo_process_cookie(yd, pair->value);
 			break;
@@ -747,6 +750,7 @@ struct _yahoo_im {
 
 struct _yahoo_im {
 	char *from;
+	char *active_id;
 	int time;
 	int utf8;
 	int buddy_icon;
@@ -775,6 +779,8 @@ static void yahoo_process_message(Purple
 				im->time = time(NULL);
 				im->utf8 = TRUE;
 			}
+			if (im && pair->key == 5)
+				im->active_id = pair->value;
 			if (pair->key == 97)
 				if (im)
 					im->utf8 = strtol(pair->value, NULL, 10);
@@ -864,7 +870,7 @@ static void yahoo_process_message(Purple
 			pkt2 = yahoo_packet_new(YAHOO_SERVICE_MESSAGE_ACK,
 					YAHOO_STATUS_AVAILABLE, pkt->id);
 			yahoo_packet_hash(pkt2, "ssisii",
-					1, purple_connection_get_display_name(gc),
+					1, im->active_id,  /* May not always be the connection's display name */
 					5, im->from,
 					302, 430,
 					430, im->id,
@@ -1481,11 +1487,11 @@ static void yahoo_auth16_stage2(PurpleUt
 #else
 		while (split_data[++totalelements] != NULL);	
 #endif
-		if (totalelements >= 5) {
-			response_no = strtol(split_data[1], NULL, 10);
-			crumb = g_strdup(split_data[2] + strlen("crumb="));
-			yd->cookie_y = g_strdup(split_data[3] + strlen("Y="));
-			yd->cookie_t = g_strdup(split_data[4] + strlen("T="));
+		if (totalelements >= 4) {
+			response_no = strtol(split_data[0], NULL, 10);
+			crumb = g_strdup(split_data[1] + strlen("crumb="));
+			yd->cookie_y = g_strdup(split_data[2] + strlen("Y="));
+			yd->cookie_t = g_strdup(split_data[3] + strlen("T="));
 		}
 
 		g_strfreev(split_data);
@@ -1567,9 +1573,9 @@ static void yahoo_auth16_stage1_cb(Purpl
 #else
 		while (split_data[++totalelements] != NULL);	
 #endif
-		if(totalelements >= 5) {
-			response_no = strtol(split_data[1], NULL, 10);
-			token = g_strdup(split_data[2] + strlen("ymsgr="));
+		if(totalelements >= 2) {
+			response_no = strtol(split_data[0], NULL, 10);
+			token = g_strdup(split_data[1] + strlen("ymsgr="));
 		}
 
 		g_strfreev(split_data);
@@ -2172,15 +2178,13 @@ static void yahoo_packet_process(PurpleC
 	case YAHOO_SERVICE_PICTURE:
 		yahoo_process_picture(gc, pkt);
 		break;
-	case YAHOO_SERVICE_PICTURE_UPDATE:
-		yahoo_process_picture_update(gc, pkt);
-		break;
 	case YAHOO_SERVICE_PICTURE_CHECKSUM:
 		yahoo_process_picture_checksum(gc, pkt);
 		break;
 	case YAHOO_SERVICE_PICTURE_UPLOAD:
 		yahoo_process_picture_upload(gc, pkt);
 		break;
+	case YAHOO_SERVICE_PICTURE_UPDATE:
 	case YAHOO_SERVICE_AVATAR_UPDATE:
 		yahoo_process_avatar_update(gc, pkt);
 		break;
@@ -2815,6 +2819,7 @@ static void yahoo_close(PurpleConnection
 	g_free(yd->pending_chat_id);
 	g_free(yd->pending_chat_topic);
 	g_free(yd->pending_chat_goto);
+	g_strfreev(yd->profiles);
 
 	g_free(yd->current_list15_grp);
 
@@ -3194,15 +3199,16 @@ static GList *yahoo_blist_node_menu(Purp
 	}
 }
 
-static void yahoo_act_id(PurpleConnection *gc, const char *entry)
+static void yahoo_act_id(PurpleConnection *gc, PurpleRequestFields *fields)
 {
 	struct yahoo_data *yd = gc->proto_data;
+	const char *name = yd->profiles[purple_request_fields_get_choice(fields, "id")];
 
 	struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_IDACT, YAHOO_STATUS_AVAILABLE, 0);
-	yahoo_packet_hash_str(pkt, 3, entry);
+	yahoo_packet_hash_str(pkt, 3, name);
 	yahoo_packet_send_and_free(pkt, yd);
 
-	purple_connection_set_display_name(gc, entry);
+	purple_connection_set_display_name(gc, name);
 }
 
 static void
@@ -3284,9 +3290,28 @@ static void yahoo_show_act_id(PurplePlug
 
 static void yahoo_show_act_id(PurplePluginAction *action)
 {
+	PurpleRequestFields *fields;
+	PurpleRequestFieldGroup *group;
+	PurpleRequestField *field;
 	PurpleConnection *gc = (PurpleConnection *) action->context;
-	purple_request_input(gc, NULL, _("Activate which ID?"), NULL,
-					   purple_connection_get_display_name(gc), FALSE, FALSE, NULL,
+	struct yahoo_data *yd = purple_connection_get_protocol_data(gc);
+	const char *name = purple_connection_get_display_name(gc);
+	int iter;
+
+	fields = purple_request_fields_new();
+	group = purple_request_field_group_new(NULL);
+	purple_request_fields_add_group(fields, group);
+	field = purple_request_field_choice_new("id", "Activate which ID?", 0);
+	purple_request_field_group_add_field(group, field);
+
+	for (iter = 0; yd->profiles[iter]; iter++) {
+		purple_request_field_choice_add(field, yd->profiles[iter]);
+		if (purple_strequal(yd->profiles[iter], name))
+			purple_request_field_choice_set_default_value(field, iter);
+	}
+
+	purple_request_fields(gc, NULL, _("Select the ID you want to activate"), NULL,
+					   fields,
 					   _("OK"), G_CALLBACK(yahoo_act_id),
 					   _("Cancel"), NULL,
 					   purple_connection_get_account(gc), NULL, NULL,
============================================================
--- libpurple/protocols/yahoo/yahoo.h	38a6ac8aaada556549e629e5821c3ad850d98bd5
+++ libpurple/protocols/yahoo/yahoo.h	230197886b9532b82a55d86eb5e873963a518f81
@@ -130,6 +130,8 @@ struct yahoo_data {
 	guint txhandler;
 	GHashTable *friends;
 
+	char **profiles;  /* Multiple profiles can be associated with an account */
+
 	/**
 	 * This is used to keep track of the IMVironment chosen
 	 * by people you talk to.  We don't do very much with
============================================================
--- libpurple/protocols/yahoo/yahoo_picture.c	bc1a3c4a432b42cf059ac12f7ad73230e7969a21
+++ libpurple/protocols/yahoo/yahoo_picture.c	cac1ff3c1d3e9680f34a4d687b61110561a61eec
@@ -153,45 +153,6 @@ void yahoo_process_picture(PurpleConnect
 	}
 }
 
-void yahoo_process_picture_update(PurpleConnection *gc, struct yahoo_packet *pkt)
-{
-	GSList *l = pkt->hash;
-	char *who = NULL;
-	int icon = 0;
-
-	while (l) {
-		struct yahoo_pair *pair = l->data;
-
-		switch (pair->key) {
-		case 4:
-			who = pair->value;
-			break;
-		case 5:
-			/* us */
-			break;
-		/* NOTE: currently the server seems to only send 213; 206 was used
-		 * in older versions. Check whether it's still needed. */
-		case 206:
-		case 213:
-			icon = strtol(pair->value, NULL, 10);
-			break;
-		}
-		l = l->next;
-	}
-
-	if (who) {
-		if (icon == 2)
-			yahoo_send_picture_request(gc, who);
-		else if ((icon == 0) || (icon == 1)) {
-			YahooFriend *f;
-			purple_buddy_icons_set_for_user(gc->account, who, NULL, 0, NULL);
-			if ((f = yahoo_friend_find(gc, who)))
-				yahoo_friend_set_buddy_icon_need_request(f, TRUE);
-			purple_debug_misc("yahoo", "Setting user %s's icon to NULL.\n", who);
-		}
-	}
-}
-
 void yahoo_process_picture_checksum(PurpleConnection *gc, struct yahoo_packet *pkt)
 {
 	GSList *l = pkt->hash;
@@ -279,7 +240,8 @@ void yahoo_process_avatar_update(PurpleC
 		case 5:
 			/* us */
 			break;
-		case 206:
+		case 206:   /* Older versions. Still needed? */
+		case 213:   /* Newer versions */
 			/*
 			 * 0 - No icon or avatar
 			 * 1 - Using an avatar
@@ -349,8 +311,8 @@ void yahoo_send_picture_update_to_user(P
 	struct yahoo_data *yd = gc->proto_data;
 	struct yahoo_packet *pkt;
 
-	pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPDATE, YAHOO_STATUS_AVAILABLE, 0);
-	yahoo_packet_hash(pkt, "ssi", 1, purple_connection_get_display_name(gc), 5, who, 206, type);
+	pkt = yahoo_packet_new(YAHOO_SERVICE_AVATAR_UPDATE, YAHOO_STATUS_AVAILABLE, 0);
+	yahoo_packet_hash(pkt, "si", 3, who, 213, type);
 	yahoo_packet_send_and_free(pkt, yd);
 }
 
============================================================
--- libpurple/protocols/yahoo/yahoo_picture.h	7e3cfca9ba88fd99035bbb9be2a41b107c26a931
+++ libpurple/protocols/yahoo/yahoo_picture.h	d4412a10113c0035d3ca768a941ac4db0c5ee5d4
@@ -31,7 +31,6 @@ void yahoo_process_picture(PurpleConnect
 void yahoo_send_picture_update_to_user(PurpleConnection *gc, const char *who, int type);
 
 void yahoo_process_picture(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_process_picture_update(PurpleConnection *gc, struct yahoo_packet *pkt);
 void yahoo_process_picture_checksum(PurpleConnection *gc, struct yahoo_packet *pkt);
 void yahoo_process_picture_upload(PurpleConnection *gc, struct yahoo_packet *pkt);
 
============================================================
--- libpurple/util.c	9324cdd3e0bfe185123ae55873ad7ad8d16756c5
+++ libpurple/util.c	135592b6214fb986caa7b1f460636a6c56e228fb
@@ -68,6 +68,7 @@ struct _PurpleUtilFetchUrlData
 	unsigned long len;
 	unsigned long data_len;
 	gssize max_len;
+	gboolean chunked;
 };
 
 static char *custom_user_dir = NULL;
@@ -3732,41 +3733,43 @@ parse_redirect(const char *data, size_t 
 	return TRUE;
 }
 
-static size_t
-parse_content_len(const char *data, size_t data_len)
+static const char *
+find_header_content(const char *data, size_t data_len, const char *header, size_t header_len)
 {
-	size_t content_len = 0;
 	const char *p = NULL;
 
-	/* This is still technically wrong, since headers are case-insensitive
-	 * [RFC 2616, section 4.2], though this ought to catch the normal case.
-	 * Note: data is _not_ nul-terminated.
-	 */
-	if(data_len > 16) {
-		p = (strncmp(data, "Content-Length: ", 16) == 0) ? data : NULL;
-		if(!p)
-			p = (strncmp(data, "CONTENT-LENGTH: ", 16) == 0)
-				? data : NULL;
-		if(!p) {
-			p = g_strstr_len(data, data_len, "\nContent-Length: ");
-			if (p)
-				p++;
-		}
-		if(!p) {
-			p = g_strstr_len(data, data_len, "\nCONTENT-LENGTH: ");
-			if (p)
-				p++;
-		}
+	if (header_len <= 0)
+		header_len = strlen(header);
 
-		if(p)
-			p += 16;
+	/* Note: data is _not_ nul-terminated.  */
+	if (data_len > header_len) {
+		if (header[0] == '\n')
+			p = (g_strncasecmp(data, header + 1, header_len - 1) == 0) ? data : NULL;
+		if (!p)
+			p = purple_strcasestr(data, header);
+		if (p)
+			p += header_len;
 	}
 
-	/* If we can find a Content-Length header at all, try to sscanf it.
+	/* If we can find the header at all, try to sscanf it.
 	 * Response headers should end with at least \r\n, so sscanf is safe,
 	 * if we make sure that there is indeed a \n in our header.
 	 */
 	if (p && g_strstr_len(p, data_len - (p - data), "\n")) {
+		return p;
+	}
+
+	return NULL;
+}
+
+static size_t
+parse_content_len(const char *data, size_t data_len)
+{
+	size_t content_len = 0;
+	const char *p = NULL;
+
+	p = find_header_content(data, data_len, "\nContent-Length: ", sizeof("\nContent-Length: ") - 1);
+	if (p) {
 		sscanf(p, "%" G_GSIZE_FORMAT, &content_len);
 		purple_debug_misc("util", "parsed %" G_GSIZE_FORMAT "\n", content_len);
 	}
@@ -3774,8 +3777,51 @@ parse_content_len(const char *data, size
 	return content_len;
 }
 
+static gboolean
+content_is_chunked(const char *data, size_t data_len)
+{
+	gboolean chunked = FALSE;
+	const char *p = find_header_content(data, data_len, "\nTransfer-Encoding: ", sizeof("\nTransfer-Encoding: ") - 1);
+	if (p && g_strncasecmp(p, "chunked", 7) == 0)
+		chunked = TRUE;
 
+	return chunked;
+}
+
+/* Process in-place */
 static void
+process_chunked_data(char *data, gssize *len)
+{
+	gssize sz;
+	gssize nlen = 0;
+	char *p = data;
+	char *s = data;
+
+	while (*s) {
+		if (sscanf(s, "%x\r\n", &sz) != 1) {
+			purple_debug_error("util", "Error processing chunked data. Expected data length, found: %s\n", s);
+			break;
+		}
+		if (sz == 0)
+			break;
+		s = strstr(s, "\r\n") + 2;
+		g_memmove(p, s, sz);
+		p += sz;
+		s += sz;
+		nlen += sz;
+		if (*s != '\r' && *(s + 1) != '\n') {
+			purple_debug_error("util", "Error processing chunked data. Expected \\r\\n, found: %s\n", s);
+			break;
+		}
+		s += 2;
+	}
+	*p = 0;
+
+	if (len)
+		*len = nlen;
+}
+
+static void
 url_fetch_recv_cb(gpointer url_data, gint source, PurpleInputCondition cond)
 {
 	PurpleUtilFetchUrlData *gfud = url_data;
@@ -3834,6 +3880,7 @@ url_fetch_recv_cb(gpointer url_data, gin
 
 				/* No redirect. See if we can find a content length. */
 				content_len = parse_content_len(gfud->webdata, header_len);
+				gfud->chunked = content_is_chunked(gfud->webdata, header_len);
 
 				if(content_len == 0) {
 					/* We'll stick with an initial 8192 */
@@ -3906,6 +3953,11 @@ url_fetch_recv_cb(gpointer url_data, gin
 		gfud->webdata = g_realloc(gfud->webdata, gfud->len + 1);
 		gfud->webdata[gfud->len] = '\0';
 
+		if (!gfud->include_headers && gfud->chunked) {
+			/* Process only if we don't want the headers. */
+			process_chunked_data(gfud->webdata, &gfud->len);
+		}
+
 		gfud->callback(gfud, gfud->user_data, gfud->webdata, gfud->len, NULL);
 		purple_util_fetch_url_cancel(gfud);
 	}


More information about the Commits mailing list