# HG changeset patch # User Yoshiki Yazawa # Date 1270358456 -32400 # Node ID 34d787feb17c1b6ea96653c992f2d02378ea8ad1 # Parent 70e67a2fa0ca6ebe5d52d7a5166d674a1ffce67c# Parent 6cfc9cf2e8cc05e42f3638b63e6aa0168cedb724 merged with im.pidgin.pidgin diff -r 70e67a2fa0ca -r 34d787feb17c COPYRIGHT --- 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 diff -r 70e67a2fa0ca -r 34d787feb17c ChangeLog --- 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: diff -r 70e67a2fa0ca -r 34d787feb17c configure.ac --- 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" diff -r 70e67a2fa0ca -r 34d787feb17c doc/finch.1.in --- 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] diff -r 70e67a2fa0ca -r 34d787feb17c finch/libgnt/gntentry.c --- 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); diff -r 70e67a2fa0ca -r 34d787feb17c finch/libgnt/gntentry.h --- 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 diff -r 70e67a2fa0ca -r 34d787feb17c libpurple/protocols/jabber/auth_cyrus.c --- 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; } diff -r 70e67a2fa0ca -r 34d787feb17c libpurple/protocols/novell/novell.c --- 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; } diff -r 70e67a2fa0ca -r 34d787feb17c libpurple/protocols/yahoo/libyahoo.c --- 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); diff -r 70e67a2fa0ca -r 34d787feb17c libpurple/protocols/yahoo/libyahoojp.c --- 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); diff -r 70e67a2fa0ca -r 34d787feb17c libpurple/protocols/yahoo/libymsg.c --- 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; } diff -r 70e67a2fa0ca -r 34d787feb17c libpurple/protocols/yahoo/libymsg.h --- 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/"