pidgin: 25555f05: Generalize the FQY command so it can be ...

qulogic at pidgin.im qulogic at pidgin.im
Fri Feb 27 02:16:16 EST 2009


-----------------------------------------------------------------
Revision: 25555f057b156444048f1b2fafeeaf056ac0be9c
Ancestor: 47d559275fa8784f242537fb23888a1f9d4e486d
Author: qulogic at pidgin.im
Date: 2009-02-27T07:13:20
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/25555f057b156444048f1b2fafeeaf056ac0be9c

Modified files:
        libpurple/protocols/msn/msn.c
        libpurple/protocols/msn/notification.c
        libpurple/protocols/msn/notification.h
        libpurple/protocols/msn/userlist.c
        libpurple/protocols/msn/userlist.h

ChangeLog: 

Generalize the FQY command so it can be used by different callbacks based
on the place that called it. Then automatically call an FQY when sending
the buddy list ADL's for a buddy with an unknown network. Then we can send
a corrected ADL later with the network from the FQY.

This should make it easier for people with OCS/Yahoo contacts that were
added incorrectly by previous versions, as they shouldn't need to mess with
their address book outside of Pidgin (but if there are multiple buddy
copies, that may need fixing externally). I should probably figure out how
to permanently fix the Membership lists, eventually.

References #6755.
References #3322

-------------- next part --------------
============================================================
--- libpurple/protocols/msn/msn.c	f847fe0be0f75c39e9cc4ebfdce82a15332329ca
+++ libpurple/protocols/msn/msn.c	c555a864b54dca93e4e52d35ef054ebe2d01ac46
@@ -1466,9 +1466,18 @@ msn_add_buddy(PurpleConnection *gc, Purp
 		   what to do with users already in the list and stuff... */
 		msn_userlist_add_buddy(userlist, who, group ? group->name : NULL);
 	} else {
+		char **tokens;
+		char *fqy;
 		/* We need to check the network for this buddy first */
 		msn_userlist_save_pending_buddy(userlist, who, group ? group->name : NULL);
-		msn_notification_send_fqy(session, who);
+		tokens = g_strsplit(who, "@", 2);
+		fqy = g_strdup_printf("<ml><d n=\"%s\"><c n=\"%s\"/></d></ml>",
+		                      tokens[1],
+		                      tokens[0]);
+		msn_notification_send_fqy(session, fqy, strlen(fqy),
+		                          (MsnFqyCb)msn_userlist_add_pending_buddy);
+		g_free(fqy);
+		g_strfreev(tokens);
 	}
 }
 
============================================================
--- libpurple/protocols/msn/notification.c	a74a1c4d67ffdb2b7074d9600fe0563176c2fb4e
+++ libpurple/protocols/msn/notification.c	f1b1dca6bfb4d81532fa3650b37be4110df66c2f
@@ -544,17 +544,16 @@ msn_add_contact_xml(MsnSession *session,
 	}
 
 	/*find a domain Node*/
-	for(d_node = xmlnode_get_child(mlNode,"d"); d_node; d_node = xmlnode_get_next_twin(d_node))
-	{
+	for (d_node = xmlnode_get_child(mlNode, "d"); d_node;
+	     d_node = xmlnode_get_next_twin(d_node)) {
 		const char *attr = xmlnode_get_attrib(d_node,"n");
 		if (attr == NULL)
 			continue;
-		if (!strcmp(attr,domain))
+		if (!strcmp(attr, domain))
 			break;
 	}
 
-	if(d_node == NULL)
-	{
+	if (d_node == NULL) {
 		/*domain not found, create a new domain Node*/
 		purple_debug_info("msn", "Didn't find existing domain node, adding one.\n");
 		d_node = xmlnode_new("d");
@@ -566,21 +565,19 @@ msn_add_contact_xml(MsnSession *session,
 	c_node = xmlnode_new("c");
 	xmlnode_set_attrib(c_node, "n", email);
 
-	purple_debug_info("msn", "list_op: %d\n", list_op);
-	g_snprintf(fmt_str, sizeof(fmt_str), "%d", list_op);
-	xmlnode_set_attrib(c_node, "l", fmt_str);
+	if (list_op != 0) {
+		purple_debug_info("msn", "list_op: %d\n", list_op);
+		g_snprintf(fmt_str, sizeof(fmt_str), "%d", list_op);
+		xmlnode_set_attrib(c_node, "l", fmt_str);
+	}
 
-	if (networkId != MSN_NETWORK_UNKNOWN)
+	if (networkId != MSN_NETWORK_UNKNOWN) {
 		g_snprintf(fmt_str, sizeof(fmt_str), "%d", networkId);
-	else if (msn_user_is_yahoo(session->account, passport))
-		g_snprintf(fmt_str, sizeof(fmt_str), "%d", MSN_NETWORK_YAHOO);
-	else
-		g_snprintf(fmt_str, sizeof(fmt_str), "%d", MSN_NETWORK_PASSPORT);
+		/*mobile*/
+		/*type_str = g_strdup_printf("4");*/
+		xmlnode_set_attrib(c_node, "t", fmt_str);
+	}
 
-	/*mobile*/
-	/*type_str = g_strdup_printf("4");*/
-	xmlnode_set_attrib(c_node, "t", fmt_str);
-
 	xmlnode_insert_child(d_node, c_node);
 
 	g_strfreev(tokens);
@@ -596,6 +593,48 @@ msn_notification_post_adl(MsnCmdProc *cm
 	msn_cmdproc_send_trans(cmdproc, trans);
 }
 
+void
+msn_notification_send_fqy(MsnSession *session,
+                          const char *payload, int payload_len,
+                          MsnFqyCb cb)
+{
+	MsnTransaction *trans;
+	MsnCmdProc *cmdproc;
+
+	cmdproc = session->notification->cmdproc;
+
+	trans = msn_transaction_new(cmdproc, "FQY", "%d", payload_len);
+	msn_transaction_set_payload(trans, payload, payload_len);
+	msn_transaction_set_data(trans, cb);
+	msn_cmdproc_send_trans(cmdproc, trans);
+}
+
+static void
+update_contact_network(MsnSession *session, const char *passport, MsnNetwork network)
+{
+	MsnUser *user = msn_userlist_find_user(session->userlist, passport);
+	/* TODO: Also figure out how to update membership lists */
+	if (user) {
+		xmlnode *adl_node;
+		char *payload;
+		int payload_len;
+
+		msn_user_set_network(user, network);
+
+		adl_node = xmlnode_new("ml");
+		xmlnode_set_attrib(adl_node, "l", "1");
+		msn_add_contact_xml(session, adl_node, passport,
+				user->list_op & MSN_LIST_OP_MASK, network);
+		payload = xmlnode_to_str(adl_node, &payload_len);
+		msn_notification_post_adl(session->notification->cmdproc, payload, payload_len);
+
+	} else {
+		purple_debug_error("msn",
+		                   "Got FQY update for unkwown user %s on network %d.\n",
+		                   passport, network);
+	}
+}
+
 /*dump contact info to NS*/
 void
 msn_notification_dump_contact(MsnSession *session)
@@ -603,14 +642,17 @@ msn_notification_dump_contact(MsnSession
 	MsnUser *user;
 	GList *l;
 	xmlnode *adl_node;
+	xmlnode *fqy_node;
 	char *payload;
 	int payload_len;
 	int adl_count = 0;
+	int fqy_count = 0;
 	const char *display_name;
 
 	adl_node = xmlnode_new("ml");
 	adl_node->child = NULL;
 	xmlnode_set_attrib(adl_node, "l", "1");
+	fqy_node = xmlnode_new("ml");
 
 	/*get the userlist*/
 	for (l = session->userlist->users; l != NULL; l = l->next) {
@@ -635,36 +677,63 @@ msn_notification_dump_contact(MsnSession
 			msn_userlist_rem_buddy_from_list(session->userlist, user->passport, MSN_LIST_AL);
 		}
 
-		msn_add_contact_xml(session, adl_node, user->passport,
-			user->list_op & MSN_LIST_OP_MASK, user->networkid);
+		if (user->networkid != MSN_NETWORK_UNKNOWN) {
+			msn_add_contact_xml(session, adl_node, user->passport,
+				user->list_op & MSN_LIST_OP_MASK, user->networkid);
 
-		/* each ADL command may contain up to 150 contacts */
-		if (++adl_count % 150 == 0 || l->next == NULL) {
-			payload = xmlnode_to_str(adl_node,&payload_len);
+			/* each ADL command may contain up to 150 contacts */
+			if (++adl_count % 150 == 0) {
+				payload = xmlnode_to_str(adl_node, &payload_len);
 
-			msn_notification_post_adl(session->notification->cmdproc,
-				payload, payload_len);
+				msn_notification_post_adl(session->notification->cmdproc,
+					payload, payload_len);
 
-			g_free(payload);
-			xmlnode_free(adl_node);
+				g_free(payload);
+				xmlnode_free(adl_node);
 
-			if (l->next) {
 				adl_node = xmlnode_new("ml");
 				adl_node->child = NULL;
 				xmlnode_set_attrib(adl_node, "l", "1");
 			}
+		} else {
+			msn_add_contact_xml(session, fqy_node, user->passport,
+				0, user->networkid);
+
+			/* each FQY command may contain up to 150 contacts, probably */
+			if (++fqy_count % 150 == 0) {
+				payload = xmlnode_to_str(fqy_node, &payload_len);
+
+				msn_notification_send_fqy(session, payload, payload_len,
+				                          update_contact_network);
+
+				g_free(payload);
+				xmlnode_free(fqy_node);
+				fqy_node = xmlnode_new("ml");
+			}
 		}
 	}
 
-	if (adl_count == 0) {
-		payload = xmlnode_to_str(adl_node,&payload_len);
+	/* Send the rest, or just an empty one to let the server set us online */
+	if (adl_count == 0 || adl_count % 150 != 0) {
+		payload = xmlnode_to_str(adl_node, &payload_len);
 
 		msn_notification_post_adl(session->notification->cmdproc, payload, payload_len);
 
 		g_free(payload);
-		xmlnode_free(adl_node);
 	}
 
+	if (fqy_count % 150 != 0) {
+		payload = xmlnode_to_str(fqy_node, &payload_len);
+
+		msn_notification_send_fqy(session, payload, payload_len,
+		                          update_contact_network);
+
+		g_free(payload);
+	}
+
+	xmlnode_free(adl_node);
+	xmlnode_free(fqy_node);
+
 	display_name = purple_connection_get_display_name(session->account->gc);
 	if (display_name
 	    && strcmp(display_name,
@@ -674,30 +743,6 @@ msn_notification_dump_contact(MsnSession
 
 }
 
-/*Post FQY to NS,Inform add a Yahoo User*/
-void
-msn_notification_send_fqy(MsnSession *session, const char *passport)
-{
-	MsnTransaction *trans;
-	MsnCmdProc *cmdproc;
-	char* email,*domain,*payload;
-	char **tokens;
-
-	cmdproc = session->notification->cmdproc;
-
-	tokens = g_strsplit(passport, "@", 2);
-	email = tokens[0];
-	domain = tokens[1];
-
-	payload = g_strdup_printf("<ml><d n=\"%s\"><c n=\"%s\"/></d></ml>", domain, email);
-	trans = msn_transaction_new(cmdproc, "FQY","%" G_GSIZE_FORMAT, strlen(payload));
-	msn_transaction_set_payload(trans, payload, strlen(payload));
-	msn_cmdproc_send_trans(cmdproc, trans);
-
-	g_free(payload);
-	g_strfreev(tokens);
-}
-
 static void
 blp_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
 {
@@ -861,7 +906,7 @@ fqy_cmd_post(MsnCmdProc *cmdproc, MsnCom
 fqy_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
 			 size_t len)
 {
-	MsnUserList *userlist;
+	MsnSession *session;
 	xmlnode *ml, *d, *c;
 	const char *domain;
 	const char *local;
@@ -869,26 +914,37 @@ fqy_cmd_post(MsnCmdProc *cmdproc, MsnCom
 	char *passport;
 	MsnNetwork network = MSN_NETWORK_PASSPORT;
 
-	userlist = cmdproc->session->userlist;
+	session = cmdproc->session;
 
 	/* FQY response:
 	    <ml><d n="domain.com"><c n="local-node" t="network" /></d></ml> */
 	ml = xmlnode_from_str(payload, len);
-	d = xmlnode_get_child(ml, "d");
-	c = xmlnode_get_child(d, "c");
-	domain = xmlnode_get_attrib(d, "n");
-	local = xmlnode_get_attrib(c, "n");
-	type = xmlnode_get_attrib(c, "t");
+	for (d = xmlnode_get_child(ml, "d");
+	     d != NULL;
+	     d = xmlnode_get_next_twin(d)) {
+		domain = xmlnode_get_attrib(d, "n");
+		for (c = xmlnode_get_child(d, "c");
+		     c != NULL;
+		     c = xmlnode_get_next_twin(c)) {
+			local = xmlnode_get_attrib(c, "n");
+			type = xmlnode_get_attrib(c, "t");
 
-	passport = g_strdup_printf("%s@%s", local, domain);
+			passport = g_strdup_printf("%s@%s", local, domain);
 
-	if (type != NULL)
-		network = (MsnNetwork)strtoul(type, NULL, 10);
-	purple_debug_info("msn", "FQY response says %s is from network %d\n",
-	                  passport, network);
-	msn_userlist_add_pending_buddy(userlist, passport, network);
+			if (type != NULL)
+				network = (MsnNetwork)strtoul(type, NULL, 10);
+			else
+				network = MSN_NETWORK_PASSPORT;
 
-	g_free(passport);
+			purple_debug_info("msn", "FQY response says %s is from network %d\n",
+			                  passport, network);
+			if (cmd->trans->data)
+				((MsnFqyCb)cmd->trans->data)(session, passport, network);
+
+			g_free(passport);
+		}
+	}
+
 	xmlnode_free(ml);
 }
 
============================================================
--- libpurple/protocols/msn/notification.h	f5bb9ed4c5bcdceb4de6d8b96b833671b40db1b5
+++ libpurple/protocols/msn/notification.h	c5fda71615516de493ca7e188a4573602e0e67fc
@@ -58,6 +58,8 @@ struct _MsnNotification
 	gboolean in_use;
 };
 
+typedef void (*MsnFqyCb)(MsnSession *session, const char *passport, MsnNetwork network);
+
 #include "state.h"
 void uum_send_msg(MsnSession *session,MsnMessage *msg);
 
@@ -69,7 +71,9 @@ void msn_notification_rem_buddy_from_lis
 void msn_notification_rem_buddy_from_list(MsnNotification *notification,
 					  MsnListId list_id, MsnUser *user);
 
-void msn_notification_send_fqy(MsnSession *session, const char *passport);
+void msn_notification_send_fqy(MsnSession *session,
+                               const char *payload, int payload_len,
+                               MsnFqyCb cb);
 
 MsnNotification *msn_notification_new(MsnSession *session);
 void msn_notification_destroy(MsnNotification *notification);
============================================================
--- libpurple/protocols/msn/userlist.c	74a0c3e9dec6492843df037df61e185fc4038736
+++ libpurple/protocols/msn/userlist.c	8b8355df7ccdba233c4785c22421e39277458651
@@ -770,10 +770,11 @@ void
  * Actually adds a buddy once we have the response from FQY
  */
 void
-msn_userlist_add_pending_buddy(MsnUserList *userlist,
+msn_userlist_add_pending_buddy(MsnSession *session,
                                const char *who,
                                /*MsnNetwork*/ int network)
 {
+	MsnUserList *userlist = session->userlist;
 	MsnUser *user = NULL;
 	MsnUser *user2;
 	GList *l;
============================================================
--- libpurple/protocols/msn/userlist.h	0969c0a68d870f89e8868e85bbcf2a99d556b429
+++ libpurple/protocols/msn/userlist.h	236de1e3340d8437f04814cb4b1ff27caca260d2
@@ -95,7 +95,7 @@ void msn_userlist_save_pending_buddy(Msn
 void msn_userlist_save_pending_buddy(MsnUserList *userlist,
                                      const char *who,
                                      const char *group_name);
-void msn_userlist_add_pending_buddy(MsnUserList *userlist,
+void msn_userlist_add_pending_buddy(MsnSession *session,
                                     const char *who,
                                     /*MsnNetwork*/ int network);
 void msn_userlist_move_buddy(MsnUserList *userlist, const char *who,


More information about the Commits mailing list