changeset 30085:34d787feb17c

merged with im.pidgin.pidgin
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Sun, 04 Apr 2010 14:20:56 +0900
parents 70e67a2fa0ca (current diff) 6cfc9cf2e8cc (diff)
children 49ffb40f3bcd
files configure.ac libpurple/protocols/yahoo/libyahoo.c libpurple/protocols/yahoo/libyahoojp.c libpurple/protocols/yahoo/libymsg.c libpurple/protocols/yahoo/libymsg.h
diffstat 12 files changed, 172 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Fri Apr 02 17:39:24 2010 +0900
+++ b/COPYRIGHT	Sun Apr 04 14:20:56 2010 +0900
@@ -148,6 +148,7 @@
 Marc Etcheverry
 David Everly
 Larry Ewing
+Facebook, Inc.
 Fartash Faghri
 Gábor Farkas
 Jesse Farmer
@@ -344,6 +345,7 @@
 Gudmundur Bjarni Olafsson
 Bartosz Oler
 Oliver
+Jürgen Orschiedt
 Stefan Ott
 Shawn Outman
 Nathan Owens (pianocomp81)
@@ -384,6 +386,7 @@
 Rajesh Ranjan
 Mart Raudsepp
 Etan Reisner
+David Reiss
 Luoh Ren-Shan
 Daniele Ricci
 Kristian Rietveld
--- a/ChangeLog	Fri Apr 02 17:39:24 2010 +0900
+++ b/ChangeLog	Sun Apr 04 14:20:56 2010 +0900
@@ -73,11 +73,19 @@
 	* Validate the hash on incoming BoB data objects (for custom smileys etc.),
 	  cache based per JID when the CID is not a valid hash (as specified by the
 	  BoB XEP).
-
-	Yahoo:
+	* Present a better error message when authentication fails while trying
+	  to connect to Facebook.  (David Reiss, Facebook)
+
+	Yahoo/Yahoo JAPAN:
 	* Attempt to better handle transparent proxies interfering with HTTP-based
 	  login.
 	* Fix handling of P2P packets, thus fixing the loss of some messages.
+	* Retrieve the pager server address from Yahoo!'s servers directly.
+	* Removed the "Pager server" account option, as it is no longer needed.
+
+	Finch:
+	* New action 'history-search', with default binding ctrl+r, to search
+	  the entered string in the input history.
 
 version 2.6.6 (02/18/2010):
 	libpurple:
--- a/configure.ac	Fri Apr 02 17:39:24 2010 +0900
+++ b/configure.ac	Sun Apr 04 14:20:56 2010 +0900
@@ -1463,7 +1463,7 @@
 			done
 
 			if test -z $DBUS_SERVICES_DIR ; then
-				AC_MSG_ERROR([D-Bus services directory was not found!  Please use --with-dbus-services and specify it's location.])
+				AC_MSG_ERROR([D-Bus services directory was not found!  Please use --with-dbus-services and specify its location.])
 			fi
 		else
 			DBUS_SERVICES_DIR="$datadir/dbus-1/services"
--- a/doc/finch.1.in	Fri Apr 02 17:39:24 2010 +0900
+++ b/doc/finch.1.in	Sun Apr 04 14:20:56 2010 +0900
@@ -348,6 +348,16 @@
 a-d = delete-next-word
 .br
 c-v = clipboard-paste
+.br
+c-p = history-prev
+.br
+c-n = history-next
+.br
+c-r = history-search
+.br
+c-up = history-prev
+.br
+c-down = history-next
 
 .br
 [GntTree::binding]
--- a/finch/libgnt/gntentry.c	Fri Apr 02 17:39:24 2010 +0900
+++ b/finch/libgnt/gntentry.c	Sun Apr 04 14:20:56 2010 +0900
@@ -55,6 +55,11 @@
 	GntEntryAction last;
 };
 
+struct _GntEntrySearch
+{
+	char *needle;
+};
+
 static guint signals[SIGS] = { 0 };
 
 static GntWidgetClass *parent_class = NULL;
@@ -471,6 +476,55 @@
 }
 
 static gboolean
+history_search(GntBindable *bind, GList *null)
+{
+	GntEntry *entry = GNT_ENTRY(bind);
+	GList *iter;
+	const char *current , *pos;
+	int len;
+	
+	if (entry->history->prev && entry->search->needle)
+		current = entry->search->needle;
+	else
+		current = gnt_entry_get_text(entry);
+
+	if (!entry->histlength || !entry->history->next || !*current)
+		return FALSE;
+
+	len = g_utf8_strlen(current, -1);
+
+	for (iter = entry->history->next; iter; iter = iter->next) {
+		const char *str = iter->data;
+		/* A more utf8-friendly version of strstr would have been better, but
+		 * for now, this will have to do. */
+		if ((pos = strstr(str, current)))
+			break;
+	}
+
+	if (!iter)
+		return TRUE;
+
+	if (entry->history->prev == NULL) {
+		/* We are doing it for the first time. Save the current contents */
+		char *text = g_strdup(gnt_entry_get_text(entry));
+
+		g_free(entry->search->needle);
+		entry->search->needle = g_strdup(current);
+
+		g_free(entry->history->data);
+		entry->history->data = text;
+	}
+
+	entry->history = iter;
+	gnt_entry_set_text_internal(entry, entry->history->data);
+	destroy_suggest(entry);
+	entry_text_changed(entry);
+
+	update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
+	return TRUE;
+}
+
+static gboolean
 clipboard_paste(GntBindable *bind, GList *n)
 {
 	GntEntry *entry = GNT_ENTRY(bind);
@@ -833,6 +887,9 @@
 		gnt_widget_destroy(entry->ddown->parent);
 	}
 
+	g_free(entry->search->needle);
+	g_free(entry->search);
+
 	jail_killring(entry->killring);
 }
 
@@ -935,6 +992,8 @@
 				GNT_KEY_CTRL_UP, NULL);
 	gnt_bindable_register_binding(bindable, "history-prev", GNT_KEY_CTRL_P, NULL);
 	gnt_bindable_register_binding(bindable, "history-next", GNT_KEY_CTRL_N, NULL);
+	gnt_bindable_class_register_action(bindable, "history-search", history_search,
+				GNT_KEY_CTRL_R, NULL);
 	gnt_bindable_class_register_action(bindable, "clipboard-paste", clipboard_paste,
 				GNT_KEY_CTRL_V, NULL);
 
@@ -966,6 +1025,7 @@
 	entry->always = FALSE;
 	entry->suggests = NULL;
 	entry->killring = new_killring();
+	entry->search = g_new0(GntEntrySearch, 1);
 
 	GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry),
 			GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW | GNT_WIDGET_CAN_TAKE_FOCUS);
--- a/finch/libgnt/gntentry.h	Fri Apr 02 17:39:24 2010 +0900
+++ b/finch/libgnt/gntentry.h	Sun Apr 04 14:20:56 2010 +0900
@@ -49,6 +49,7 @@
 typedef struct _GntEntryPriv		GntEntryPriv;
 typedef struct _GntEntryClass	GntEntryClass;
 typedef struct _GntEntryKillRing    GntEntryKillRing;
+typedef struct _GntEntrySearch		GntEntrySearch;
 
 typedef enum
 {
@@ -86,6 +87,7 @@
 	gboolean always;    /* Should the list of suggestions show at all times, or only on tab-press? */
 	GntWidget *ddown;   /* The dropdown with the suggested list */
 	GntEntryKillRing *killring; /**< @since 2.3.0 */
+	GntEntrySearch *search;		/**< @since 2.7.0 */
 };
 
 struct _GntEntryClass
--- a/libpurple/protocols/jabber/auth_cyrus.c	Fri Apr 02 17:39:24 2010 +0900
+++ b/libpurple/protocols/jabber/auth_cyrus.c	Sun Apr 04 14:20:56 2010 +0900
@@ -404,11 +404,13 @@
 			continue;
 		}
 
-		/* Don't include Google Talk's X-GOOGLE-TOKEN mechanism, as we will not
-		 * support it and including it gives a false fall-back to other mechs offerred,
-		 * leading to incorrect error handling.
+		/* Don't include Google Talk's X-GOOGLE-TOKEN mechanism
+		 * or Facebook Chat's X-FACEBOOK-PLATFORM mechansim,
+		 * as we will not support them and including them gives a false fall-back
+		 * to other mechs offerred, leading to incorrect error handling.
 		 */
-		if (g_str_equal(mech_name, "X-GOOGLE-TOKEN")) {
+		if (g_str_equal(mech_name, "X-GOOGLE-TOKEN")
+				|| g_str_equal(mech_name, "X-FACEBOOK-PLATFORM") ) {
 			g_free(mech_name);
 			continue;
 		}
--- a/libpurple/protocols/novell/novell.c	Fri Apr 02 17:39:24 2010 +0900
+++ b/libpurple/protocols/novell/novell.c	Sun Apr 04 14:20:56 2010 +0900
@@ -1458,7 +1458,7 @@
 		for (node = rem_list; node; node = node->next) {
 			purple_privacy_permit_remove(gc->account, (char *)node->data, TRUE);
 		}
-		g_free(rem_list);
+		g_slist_free(rem_list);
 		rem_list = NULL;
 	}
 
--- a/libpurple/protocols/yahoo/libyahoo.c	Fri Apr 02 17:39:24 2010 +0900
+++ b/libpurple/protocols/yahoo/libyahoo.c	Sun Apr 04 14:20:56 2010 +0900
@@ -308,9 +308,6 @@
 {
 	PurpleAccountOption *option;
 
-	option = purple_account_option_string_new(_("Pager server"), "server", YAHOO_PAGER_HOST);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-
 	option = purple_account_option_int_new(_("Pager port"), "port", YAHOO_PAGER_PORT);
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
 
--- a/libpurple/protocols/yahoo/libyahoojp.c	Fri Apr 02 17:39:24 2010 +0900
+++ b/libpurple/protocols/yahoo/libyahoojp.c	Sun Apr 04 14:20:56 2010 +0900
@@ -204,10 +204,7 @@
 {
 	PurpleAccountOption *option;
 
-	option = purple_account_option_string_new(_("Pager server"), "server", YAHOOJP_PAGER_HOST);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
-
-	option = purple_account_option_int_new(_("Pager port"), "port", YAHOOJP_PAGER_PORT);
+	option = purple_account_option_int_new(_("Pager port"), "port", YAHOO_PAGER_PORT);
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
 
 	option = purple_account_option_string_new(_("File transfer server"), "xfer_host", YAHOOJP_XFER_HOST);
--- a/libpurple/protocols/yahoo/libymsg.c	Fri Apr 02 17:39:24 2010 +0900
+++ b/libpurple/protocols/yahoo/libymsg.c	Sun Apr 04 14:20:56 2010 +0900
@@ -1742,6 +1742,8 @@
 				244, yd->jp ? YAHOOJP_CLIENT_VERSION_ID : YAHOO_CLIENT_VERSION_ID,
 				2, name,
 				2, "1",
+				/* Should send key 59, value of bcookie here--need to fetch it first! */
+				98, purple_account_get_string(account, "room_list_locale", yd->jp ? "jp" : "us"),
 				135, yd->jp ? YAHOOJP_CLIENT_VERSION : YAHOO_CLIENT_VERSION);
 
 	if (yd->picture_checksum)
@@ -1900,7 +1902,8 @@
 					break;
 				case 1213:
 					/* security lock from too many failed login attempts */
-					error_reason = g_strdup(_("Account locked: Too many failed login attempts.  Logging into the Yahoo! website may fix this."));
+					error_reason = g_strdup(_("Account locked: Too many failed login "
+								"attempts.  Logging into the Yahoo! website may fix this."));
 					error = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
 					break;
 				case 1235:
@@ -1909,9 +1912,16 @@
 					error = PURPLE_CONNECTION_ERROR_INVALID_USERNAME;
 					break;
 				case 1214:
+					/* indicates a lock of some description */
+					error_reason = g_strdup(_("Account locked: Unknown reason.  Logging "
+								"into the Yahoo! website may fix this."));
+					error = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
+					break;
 				case 1236:
-					/* indicates a lock of some description */
-					error_reason = g_strdup(_("Account locked: Unknown reason.  Logging into the Yahoo! website may fix this."));
+					/* indicates a lock due to logging in too frequently */
+					error_reason = g_strdup(_("Account locked: You have been logging in too "
+								"frequently.  Wait a few minutes before trying to connect "
+								"again.  Logging into the Yahoo! website may help."));
 					error = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
 					break;
 				case 100:
@@ -3457,17 +3467,6 @@
 }
 #endif /* TRY_WEBMESSENGER_LOGIN */
 
-static void yahoo_server_check(PurpleAccount *account)
-{
-	const char *server;
-
-	server = purple_account_get_string(account, "server", YAHOO_PAGER_HOST);
-
-	if (*server == '\0' || g_str_equal(server, "scs.yahoo.com") ||
-			g_str_equal(server, "scs.msg.yahoo.com"))
-		purple_account_set_string(account, "server", YAHOO_PAGER_HOST);
-}
-
 static void yahoo_picture_check(PurpleAccount *account)
 {
 	PurpleConnection *gc = purple_account_get_connection(account);
@@ -3522,12 +3521,61 @@
 	}
 }
 
+static void yahoo_got_pager_server(PurpleUtilFetchUrlData *url_data,
+		gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message)
+{
+	YahooData *yd = user_data;
+	PurpleConnection *gc = yd->gc;
+	PurpleAccount *a = purple_connection_get_account(gc);
+	gchar **strings = NULL, *cs_server = NULL;
+	int port = 0, stringslen = 0;
+
+	if(error_message != NULL || len == 0) {
+		purple_debug_error("yahoo", "Unable to retrieve server info. %"
+				G_GSIZE_FORMAT " bytes retrieved with error message: %s\n", len,
+				error_message ? error_message : "(null)");
+		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+				_("Unable to connect: The server returned an empty response."));
+	} else {
+		strings = g_strsplit(url_text, "\r\n", -1);
+
+		if((stringslen = g_strv_length(strings)) > 1) {
+			int i;
+
+			for(i = 0; i < stringslen; i++) {
+				if(g_ascii_strncasecmp(strings[i], "COLO_CAPACITY=", 14) == 0) {
+					purple_debug_info("yahoo", "Got COLO Capacity: %s\n", &(strings[i][14]));
+				} else if(g_ascii_strncasecmp(strings[i], "CS_IP_ADDRESS=", 14) == 0) {
+					cs_server = g_strdup(&strings[i][14]);
+					purple_debug_info("yahoo", "Got CS IP address: %s\n", cs_server);
+				}
+			}
+		}
+
+		if(cs_server) { /* got an address; get on with connecting */
+			port = purple_account_get_int(a, "port", YAHOO_PAGER_PORT);
+
+			if(purple_proxy_connect(gc, a, cs_server, port, yahoo_got_connected, gc) == NULL)
+				purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+								_("Unable to connect"));
+		} else {
+			purple_debug_error("yahoo", "No CS address retrieved!  Server "
+					"response:\n%s\n", url_text ? url_text : "(null)");
+			purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+					_("Unable to connect: The server's response did not contain "
+						"the necessary information"));
+		}
+	}
+
+	g_strfreev(strings);
+	g_free(cs_server);
+}
+
 void yahoo_login(PurpleAccount *account) {
 	PurpleConnection *gc = purple_account_get_connection(account);
 	YahooData *yd = gc->proto_data = g_new0(YahooData, 1);
 	PurpleStatus *status = purple_account_get_active_status(account);
-	const char *server = NULL;
-	int pager_port = 0;
+	gboolean use_whole_url = yahoo_account_use_http_proxy(gc);
 
 	gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC;
 
@@ -3536,6 +3584,7 @@
 	purple_connection_set_display_name(gc, purple_account_get_username(account));
 
 	yd->gc = gc;
+	yd->jp = yahoo_is_japan(account);
 	yd->yahoo_local_p2p_server_fd = -1;
 	yd->fd = -1;
 	yd->txhandler = 0;
@@ -3554,19 +3603,17 @@
 	yd->last_keepalive = yd->last_ping = time(NULL);
 
 	yd->current_status = get_yahoo_status_from_purple_status(status);
-	yd->jp = yahoo_is_japan(account);
-
-	yahoo_server_check(account);
+
 	yahoo_picture_check(account);
 
-	server = purple_account_get_string(account, "server",
-					yd->jp ? YAHOOJP_PAGER_HOST : YAHOO_PAGER_HOST);
-	pager_port = purple_account_get_int(account, "port",
-					yd->jp ? YAHOOJP_PAGER_PORT : YAHOO_PAGER_PORT);
-
-	if (purple_proxy_connect(gc, account, server, pager_port, yahoo_got_connected, gc) == NULL)
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-						_("Unable to connect"));
+	/* Get the pager server.  Actually start connecting in the callback since we
+	 * must have the contents of the HTTP response to proceed. */
+	purple_util_fetch_url_request_len_with_account(
+			purple_connection_get_account(gc),
+			yd->jp ? YAHOOJP_PAGER_HOST_REQ_URL : YAHOO_PAGER_HOST_REQ_URL,
+			use_whole_url ? TRUE : FALSE,
+			YAHOO_CLIENT_USERAGENT, TRUE, NULL, FALSE, -1,
+			yahoo_got_pager_server, yd);
 
 	return;
 }
--- a/libpurple/protocols/yahoo/libymsg.h	Fri Apr 02 17:39:24 2010 +0900
+++ b/libpurple/protocols/yahoo/libymsg.h	Sun Apr 04 14:20:56 2010 +0900
@@ -29,7 +29,7 @@
 #include "cmds.h"
 #include "prpl.h"
 
-#define YAHOO_PAGER_HOST "scsa.msg.yahoo.com"
+#define YAHOO_PAGER_HOST_REQ_URL "http://vcs1.msg.yahoo.com/capacity"
 #define YAHOO_PAGER_PORT 5050
 #define YAHOO_PAGER_PORT_P2P 5101
 #define YAHOO_LOGIN_URL "https://login.yahoo.com/config/pwtoken_login?src=ymsgr&ts=&token=%s"
@@ -44,10 +44,9 @@
 #define YAHOO_XFER_RELAY_PORT 80
 #define YAHOO_ROOMLIST_URL "http://insider.msg.yahoo.com/ycontent/"
 #define YAHOO_ROOMLIST_LOCALE "us"
-/* really we should get the list of servers from
- http://update.messenger.yahoo.co.jp/servers.html */
-#define YAHOOJP_PAGER_HOST "cs1.msg.vip.ogk.yahoo.co.jp"
-#define YAHOOJP_PAGER_PORT 80
+
+/* Yahoo! JAPAN stuff */
+#define YAHOOJP_PAGER_HOST_REQ_URL "http://cs1.msg.vip.ogk.yahoo.co.jp/capacity"
 #define YAHOOJP_TOKEN_URL "https://login.yahoo.co.jp/config/pwtoken_get?src=ymsgr&ts=&login=%s&passwd=%s&chal=%s"
 #define YAHOOJP_LOGIN_URL "https://login.yahoo.co.jp/config/pwtoken_login?src=ymsgr&ts=&token=%s"
 #define YAHOOJP_PROFILE_URL "http://profiles.yahoo.co.jp/"