diff options
author | Richard Laager <rlaager@pidgin.im> | 2007-11-17 00:12:30 +0000 |
---|---|---|
committer | Richard Laager <rlaager@pidgin.im> | 2007-11-17 00:12:30 +0000 |
commit | ae1aed78e0493ddd32f1e9d877a28bd2ed175219 (patch) | |
tree | f8314b54759b3b346234527c9141adbfea24fd8a /libpurple/protocols/yahoo | |
parent | 3203aa10b6a6137d12536be976a9d6f2f73982da (diff) | |
parent | 3f7f2c1ad2ebdb88c5d582f9524eb1ea68b7f265 (diff) | |
download | pidgin-ae1aed78e0493ddd32f1e9d877a28bd2ed175219.tar.gz |
This merge has the effect of reverting the hinting code from trunk.
Diffstat (limited to 'libpurple/protocols/yahoo')
-rw-r--r-- | libpurple/protocols/yahoo/yahoo.c | 68 | ||||
-rw-r--r-- | libpurple/protocols/yahoo/yahoo_aliases.c | 548 | ||||
-rw-r--r-- | libpurple/protocols/yahoo/yahoo_packet.c | 6 | ||||
-rw-r--r-- | libpurple/protocols/yahoo/ycht.c | 5 |
4 files changed, 321 insertions, 306 deletions
diff --git a/libpurple/protocols/yahoo/yahoo.c b/libpurple/protocols/yahoo/yahoo.c index af11c5eeee..b622893247 100644 --- a/libpurple/protocols/yahoo/yahoo.c +++ b/libpurple/protocols/yahoo/yahoo.c @@ -201,10 +201,10 @@ static void yahoo_process_status(PurpleConnection *gc, struct yahoo_packet *pkt) char *message = NULL; if (pkt->service == YAHOO_SERVICE_LOGOFF && pkt->status == -1) { - gc->wants_to_die = TRUE; if (!purple_account_get_remember_password(account)) purple_account_set_password(account, NULL); - purple_connection_error(gc, _("You have signed on from another location.")); + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NAME_IN_USE, + _("You have signed on from another location.")); return; } @@ -902,12 +902,12 @@ static void yahoo_process_message(PurpleConnection *gc, struct yahoo_packet *pkt PurpleBuddy *buddy; PurpleAccount *account; PurpleConversation *c; - char *username, *str; - - str = NULL; + char *username; account = purple_connection_get_account(gc); - c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, im->from); + c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, im->from, account); + if (c == NULL) + c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, im->from); if ((buddy = purple_find_buddy(account, im->from)) != NULL) username = g_markup_escape_text(purple_buddy_get_alias(buddy), -1); @@ -917,7 +917,6 @@ static void yahoo_process_message(PurpleConnection *gc, struct yahoo_packet *pkt serv_got_attention(gc, username, YAHOO_BUZZ); g_free(username); - g_free(str); g_free(m); g_free(im); continue; @@ -2090,13 +2089,14 @@ static void yahoo_process_authresp(PurpleConnection *gc, struct yahoo_packet *pk char *url = NULL; char *fullmsg; PurpleAccount *account = gc->account; + PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED; while (l) { struct yahoo_pair *pair = l->data; if (pair->key == 66) err = strtol(pair->value, NULL, 10); - if (pair->key == 20) + else if (pair->key == 20) url = pair->value; l = l->next; @@ -2105,6 +2105,7 @@ static void yahoo_process_authresp(PurpleConnection *gc, struct yahoo_packet *pk switch (err) { case 3: msg = g_strdup(_("Invalid screen name.")); + reason = PURPLE_CONNECTION_ERROR_INVALID_USERNAME; break; case 13: #ifdef TRY_WEBMESSENGER_LOGIN @@ -2139,8 +2140,7 @@ static void yahoo_process_authresp(PurpleConnection *gc, struct yahoo_packet *pk else fullmsg = g_strdup(msg); - gc->wants_to_die = TRUE; - purple_connection_error(gc, fullmsg); + purple_connection_error_reason(gc, reason, fullmsg); g_free(msg); g_free(fullmsg); } @@ -2463,12 +2463,13 @@ static void yahoo_pending(gpointer data, gint source, PurpleInputCondition cond) return; tmp = g_strdup_printf(_("Lost connection with server:\n%s"), - strerror(errno)); - purple_connection_error(gc, tmp); + g_strerror(errno)); + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; } else if (len == 0) { - purple_connection_error(gc, _("Server closed the connection.")); + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + _("Server closed the connection.")); return; } @@ -2559,7 +2560,7 @@ static void yahoo_got_connected(gpointer data, gint source, const gchar *error_m gchar *tmp; tmp = g_strdup_printf(_("Could not establish a connection with the server:\n%s"), error_message); - purple_connection_error(gc, tmp); + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; } @@ -2591,7 +2592,7 @@ static void yahoo_got_web_connected(gpointer data, gint source, const gchar *err gchar *tmp; tmp = g_strdup_printf(_("Could not establish a connection with the server:\n%s"), error_message); - purple_connection_error(gc, tmp); + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; } @@ -2630,12 +2631,13 @@ static void yahoo_web_pending(gpointer data, gint source, PurpleInputCondition c return; tmp = g_strdup_printf(_("Lost connection with server:\n%s"), - strerror(errno)); - purple_connection_error(gc, tmp); + g_strerror(errno)); + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; } else if (len == 0) { - purple_connection_error(gc, _("Server closed the connection.")); + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + _("Server closed the connection.")); return; } @@ -2650,7 +2652,8 @@ static void yahoo_web_pending(gpointer data, gint source, PurpleInputCondition c if ((strncmp(buf, "HTTP/1.0 302", strlen("HTTP/1.0 302")) && strncmp(buf, "HTTP/1.1 302", strlen("HTTP/1.1 302")))) { - purple_connection_error(gc, _("Received unexpected HTTP response from server.")); + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + _("Received unexpected HTTP response from server.")); return; } @@ -2672,9 +2675,10 @@ static void yahoo_web_pending(gpointer data, gint source, PurpleInputCondition c yd->rxlen = 0; /* Now we have our cookies to login with. I'll go get the milk. */ if (purple_proxy_connect(gc, account, "wcs2.msg.dcn.yahoo.com", - purple_account_get_int(account, "port", YAHOO_PAGER_PORT), - yahoo_got_web_connected, gc) == NULL) { - purple_connection_error(gc, _("Connection problem")); + purple_account_get_int(account, "port", YAHOO_PAGER_PORT), + yahoo_got_web_connected, gc) == NULL) { + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + _("Connection problem")); return; } } @@ -2701,8 +2705,8 @@ static void yahoo_got_cookies_send_cb(gpointer data, gint source, PurpleInputCon purple_input_remove(gc->inpa); gc->inpa = 0; tmp = g_strdup_printf(_("Lost connection with %s:\n%s"), - "login.yahoo.com:80", strerror(errno)); - purple_connection_error(gc, tmp); + "login.yahoo.com:80", g_strerror(errno)); + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; } @@ -2727,7 +2731,7 @@ static void yahoo_got_cookies(gpointer data, gint source, const gchar *error_mes gchar *tmp; tmp = g_strdup_printf(_("Could not establish a connection with %s:\n%s"), "login.yahoo.com:80", error_message); - purple_connection_error(gc, tmp); + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; } @@ -2811,7 +2815,8 @@ yahoo_login_page_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, if (error_message != NULL) { - purple_connection_error(gc, error_message); + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + error_message); return; } @@ -2860,7 +2865,8 @@ yahoo_login_page_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, g_hash_table_destroy(hash); yd->auth = g_string_free(url, FALSE); if (purple_proxy_connect(gc, account, "login.yahoo.com", 80, yahoo_got_cookies, gc) == NULL) { - purple_connection_error(gc, _("Connection problem")); + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + _("Connection problem")); return; } @@ -2963,7 +2969,8 @@ static void yahoo_login(PurpleAccount *account) { purple_account_get_int(account, "port", YAHOO_PAGER_PORT), yahoo_got_connected, gc) == NULL) { - purple_connection_error(gc, _("Connection problem")); + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + _("Connection problem")); return; } } else { @@ -2973,7 +2980,8 @@ static void yahoo_login(PurpleAccount *account) { purple_account_get_int(account, "port", YAHOO_PAGER_PORT), yahoo_got_connected, gc) == NULL) { - purple_connection_error(gc, _("Connection problem")); + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + _("Connection problem")); return; } } @@ -4355,7 +4363,7 @@ static PurplePluginInfo info = PURPLE_PRIORITY_DEFAULT, /**< priority */ "prpl-yahoo", /**< id */ "Yahoo", /**< name */ - VERSION, /**< version */ + DISPLAY_VERSION, /**< version */ /** summary */ N_("Yahoo Protocol Plugin"), /** description */ diff --git a/libpurple/protocols/yahoo/yahoo_aliases.c b/libpurple/protocols/yahoo/yahoo_aliases.c index 2403287e88..f31216c841 100644 --- a/libpurple/protocols/yahoo/yahoo_aliases.c +++ b/libpurple/protocols/yahoo/yahoo_aliases.c @@ -1,271 +1,277 @@ -/*
- * purple
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- *
- */
-
-
-#include "internal.h"
-
-#include "account.h"
-#include "accountopt.h"
-#include "blist.h"
-#include "debug.h"
-#include "util.h"
-#include "version.h"
-#include "yahoo.h"
-#include "yahoo_aliases.h"
-#include "yahoo_packet.h"
-
-/* I hate hardcoding this stuff, but Yahoo never sends us anything to use. Someone in the know may be able to tweak this URL */
-#define YAHOO_ALIAS_FETCH_URL "http://address.yahoo.com/yab/us?v=XM&prog=ymsgr&.intl=us&diffs=1&t=0&tags=short&rt=0&prog-ver=8.1.0.249&useutf8=1&legenc=codepage-1252"
-#define YAHOO_ALIAS_UPDATE_URL "http://address.yahoo.com/yab/us?v=XM&prog=ymsgr&.intl=us&sync=1&tags=short&noclear=1&useutf8=1&legenc=codepage-1252"
-
-void yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias);
-
-/**
- * Stuff we want passed to the callback function
- */
-struct callback_data {
- PurpleConnection *gc;
- char *id;
-};
-
-
-/**************************************************************************
- * Alias Fetch Functions
- **************************************************************************/
-
-static void
-yahoo_fetch_aliases_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data,const gchar *url_text, size_t len, const gchar *error_message)
-{
- struct callback_data *cb = user_data;
- PurpleConnection *gc = cb->gc;
- struct yahoo_data *yd = gc->proto_data;
-
- yd->url_datas = g_slist_remove(yd->url_datas, url_data);
-
- if (len == 0) {
- purple_debug_info("yahoo","No Aliases to process\n");
- } else {
- const char *yid, *full_name, *nick_name, *alias, *id, *fn, *ln, *nn;
- PurpleBuddy *b = NULL;
- xmlnode *item, *contacts;
-
- /* Put our web response into a xmlnode for easy management */
- contacts = xmlnode_from_str(url_text, -1);
-
- if (contacts == NULL) {
- purple_debug_error("yahoo_aliases","Badly formed XML\n");
- return;
- }
- purple_debug_info("yahoo", "Fetched %i bytes of alias data\n", len);
-
- /* Loop around and around and around until we have gone through all the received aliases */
- for(item = xmlnode_get_child(contacts, "ct"); item; item = xmlnode_get_next_twin(item)) {
- /* Yahoo replies with two types of contact (ct) record, we are only interested in the alias ones */
- if ((yid = xmlnode_get_attrib(item, "yi"))) {
- /* Grab all the bits of information we can */
- fn = xmlnode_get_attrib(item,"fn");
- ln = xmlnode_get_attrib(item,"ln");
- nn = xmlnode_get_attrib(item,"nn");
- id = xmlnode_get_attrib(item,"id");
-
- /* Yahoo stores first and last names separately, lets put them together into a full name */
- full_name = g_strstrip(g_strdup_printf("%s %s", (fn != NULL ? fn : "") , (ln != NULL ? ln : "")));
- nick_name = (nn != NULL ? g_strstrip(g_strdup_printf("%s", nn)) : NULL);
-
- if (nick_name != NULL)
- alias = nick_name; /* If we have a nickname from Yahoo, let's use it */
- else if (strlen(full_name) != 0)
- alias = full_name; /* If no Yahoo nickname, we can use the full_name created above */
- else
- alias = NULL; /* No nickname, first name or last name, then you get no alias !! */
-
- /* Find the local buddy that matches */
- b = purple_find_buddy(cb->gc->account, yid);
-
- /* If we don't find a matching buddy, ignore the alias !! */
- if (b != NULL) {
- /* Create an object that we can attach to the buddies proto_data pointer */
- struct YahooUser *yu;
- yu = g_new0(struct YahooUser, 1);
- yu->id = g_strdup(id);
- yu->firstname = g_strdup(fn);
- yu->lastname = g_strdup(ln);
- yu->nickname = g_strdup(nn);
- b->proto_data=yu;
-
- /* Finally, if we received an alias, we better update the buddy list */
- if (alias != NULL) {
- serv_got_alias(cb->gc, yid, alias);
- purple_debug_info("yahoo","Fetched alias '%s' (%s)\n",alias,id);
- } else if (b->alias != alias && strcmp(b->alias, "") != 0) {
- /* Or if we have an alias that Yahoo doesn't, send it up */
- yahoo_update_alias(cb->gc, yid, b->alias);
- purple_debug_info("yahoo","Sent alias '%s'\n", b->alias);
- }
- } else {
- purple_debug_info("yahoo", "Bizarre, received alias for %s, but they are not on your list...\n", yid);
- }
- }
- }
- xmlnode_free(contacts);
- }
- g_free(cb->id);
- g_free(cb);
-}
-
-void
-yahoo_fetch_aliases(PurpleConnection *gc)
-{
- struct yahoo_data *yd = gc->proto_data;
- struct callback_data *cb;
- char *url, *request, *webpage, *webaddress, *strtmp;
- int inttmp;
- PurpleUtilFetchUrlData *url_data;
-
- /* Using callback_data so I have access to gc in the callback function */
- cb = g_new0(struct callback_data, 1);
- cb->gc = gc;
-
- /* Build all the info to make the web request */
- url = g_strdup(YAHOO_ALIAS_FETCH_URL);
- purple_url_parse(url, &webaddress, &inttmp, &webpage, &strtmp, &strtmp);
- request = g_strdup_printf("GET /%s HTTP/1.1\r\n"
- "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n"
- "Cookie: T=%s; Y=%s\r\n"
- "Host: %s\r\n"
- "Cache-Control: no-cache\r\n\r\n",
- webpage, yd->cookie_t,yd->cookie_y, webaddress);
-
- /* We have a URL and some header information, let's connect and get some aliases */
- url_data = purple_util_fetch_url_request(url, FALSE, NULL, TRUE, request, FALSE, yahoo_fetch_aliases_cb, cb);
- if (url_data != NULL) {
- yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
- } else {
- g_free(cb);
- }
-
- g_free(url);
- g_free(request);
-}
-
-/**************************************************************************
- * Alias Update Functions
- **************************************************************************/
-
-static void
-yahoo_update_alias_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data,const gchar *url_text, size_t len, const gchar *error_message)
-{
- xmlnode *node, *result;
- struct callback_data *cb = user_data;
- PurpleConnection *gc = cb->gc;
- struct yahoo_data *yd;
-
- yd = gc->proto_data;
- yd->url_datas = g_slist_remove(yd->url_datas, url_data);
-
- result = xmlnode_from_str(url_text, -1);
-
- purple_debug_info("yahoo", "ID: %s, Return data: %s\n",cb->id, url_text);
-
- if (result == NULL) {
- purple_debug_error("yahoo","Alias update faild: Badly formed response\n");
- return;
- }
-
- if ((node = xmlnode_get_child(result, "ct"))) {
- if (g_ascii_strncasecmp(xmlnode_get_attrib(node, "id"), cb->id, strlen(cb->id))==0)
- purple_debug_info("yahoo", "Alias update succeeded\n");
- else
- purple_debug_error("yahoo", "Alias update failed (Contact record return mismatch)\n");
- } else {
- purple_debug_info("yahoo", "Alias update failed (No contact record returned)\n");
- }
-
- g_free(cb->id);
- g_free(cb);
- xmlnode_free(result);
-}
-
-void
-yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias)
-{
- struct yahoo_data *yd;
- struct YahooUser *yu;
- char *content, *url, *request, *webpage, *webaddress, *strtmp;
- int inttmp;
- struct callback_data *cb;
- PurpleBuddy *buddy;
- PurpleUtilFetchUrlData *url_data;
-
- g_return_if_fail(alias!= NULL);
- g_return_if_fail(who!=NULL);
- g_return_if_fail(gc!=NULL);
-
- purple_debug_info("yahoo", "Sending '%s' as new alias for user '%s'.\n",alias, who);
-
- buddy = purple_find_buddy(gc->account, who);
- if (buddy == NULL || buddy->proto_data == NULL) {
- purple_debug_info("yahoo", "Missing proto_data (get_yahoo_aliases must have failed), bailing out\n");
- return;
- }
-
- yd = gc->proto_data;
- yu = buddy->proto_data;
-
- /* Using callback_data so I have access to gc in the callback function */
- cb = g_new0(struct callback_data, 1);
- cb->id = g_strdup(yu->id);
- cb->gc = gc;
-
- /* Build all the info to make the web request */
- url = g_strdup(YAHOO_ALIAS_UPDATE_URL);
- purple_url_parse(url, &webaddress, &inttmp, &webpage, &strtmp, &strtmp);
-
- content = g_strdup_printf("<?xml version=\"1.0\" encoding=\"utf-8\"?><ab k=\"%s\" cc=\"1\">\n"
- "<ct e=\"1\" yi='%s' id='%s' nn='%s' pr='0' />\n</ab>\r\n",
- gc->account->username, who, yu->id, g_markup_escape_text(alias, strlen(alias)));
-
- request = g_strdup_printf("POST /%s HTTP/1.1\r\n"
- "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n"
- "Cookie: T=%s; Y=%s\r\n"
- "Host: %s\r\n"
- "Content-Length: %" G_GSIZE_FORMAT "\r\n"
- "Cache-Control: no-cache\r\n\r\n"
- "%s",
- webpage, yd->cookie_t,yd->cookie_y, webaddress,
- strlen(content), content);
-
- /* We have a URL and some header information, let's connect and update the alias */
- url_data = purple_util_fetch_url_request(url, FALSE, NULL, TRUE, request, FALSE, yahoo_update_alias_cb, cb);
- if (url_data != NULL) {
- yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
- } else {
- g_free(cb->id);
- g_free(cb);
- }
-
- g_free(content);
- g_free(url);
- g_free(request);
-}
-
+/* + * purple + * + * Purple is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + * + */ + + +#include "internal.h" + +#include "account.h" +#include "accountopt.h" +#include "blist.h" +#include "debug.h" +#include "util.h" +#include "version.h" +#include "yahoo.h" +#include "yahoo_aliases.h" +#include "yahoo_packet.h" + +/* I hate hardcoding this stuff, but Yahoo never sends us anything to use. Someone in the know may be able to tweak this URL */ +#define YAHOO_ALIAS_FETCH_URL "http://address.yahoo.com/yab/us?v=XM&prog=ymsgr&.intl=us&diffs=1&t=0&tags=short&rt=0&prog-ver=8.1.0.249&useutf8=1&legenc=codepage-1252" +#define YAHOO_ALIAS_UPDATE_URL "http://address.yahoo.com/yab/us?v=XM&prog=ymsgr&.intl=us&sync=1&tags=short&noclear=1&useutf8=1&legenc=codepage-1252" + +void yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias); + +/** + * Stuff we want passed to the callback function + */ +struct callback_data { + PurpleConnection *gc; + char *id; +}; + + +/************************************************************************** + * Alias Fetch Functions + **************************************************************************/ + +static void +yahoo_fetch_aliases_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data,const gchar *url_text, size_t len, const gchar *error_message) +{ + struct callback_data *cb = user_data; + PurpleConnection *gc = cb->gc; + struct yahoo_data *yd = gc->proto_data; + + yd->url_datas = g_slist_remove(yd->url_datas, url_data); + + if (len == 0) { + purple_debug_info("yahoo", "No Aliases to process.%s%s\n", + error_message ? " Error:" : "", error_message ? error_message : ""); + } else { + const char *yid, *full_name, *nick_name, *alias, *id, *fn, *ln, *nn; + PurpleBuddy *b = NULL; + xmlnode *item, *contacts; + + /* Put our web response into a xmlnode for easy management */ + contacts = xmlnode_from_str(url_text, -1); + + if (contacts == NULL) { + purple_debug_error("yahoo_aliases","Badly formed XML\n"); + return; + } + purple_debug_info("yahoo", "Fetched %i bytes of alias data\n", len); + + /* Loop around and around and around until we have gone through all the received aliases */ + for(item = xmlnode_get_child(contacts, "ct"); item; item = xmlnode_get_next_twin(item)) { + /* Yahoo replies with two types of contact (ct) record, we are only interested in the alias ones */ + if ((yid = xmlnode_get_attrib(item, "yi"))) { + /* Grab all the bits of information we can */ + fn = xmlnode_get_attrib(item,"fn"); + ln = xmlnode_get_attrib(item,"ln"); + nn = xmlnode_get_attrib(item,"nn"); + id = xmlnode_get_attrib(item,"id"); + + /* Yahoo stores first and last names separately, lets put them together into a full name */ + full_name = g_strstrip(g_strdup_printf("%s %s", (fn != NULL ? fn : "") , (ln != NULL ? ln : ""))); + nick_name = (nn != NULL ? g_strstrip(g_strdup_printf("%s", nn)) : NULL); + + if (nick_name != NULL) + alias = nick_name; /* If we have a nickname from Yahoo, let's use it */ + else if (strlen(full_name) != 0) + alias = full_name; /* If no Yahoo nickname, we can use the full_name created above */ + else + alias = NULL; /* No nickname, first name or last name, then you get no alias !! */ + + /* Find the local buddy that matches */ + b = purple_find_buddy(cb->gc->account, yid); + + /* If we don't find a matching buddy, ignore the alias !! */ + if (b != NULL) { + /* Create an object that we can attach to the buddies proto_data pointer */ + struct YahooUser *yu; + yu = g_new0(struct YahooUser, 1); + yu->id = g_strdup(id); + yu->firstname = g_strdup(fn); + yu->lastname = g_strdup(ln); + yu->nickname = g_strdup(nn); + b->proto_data=yu; + + /* Finally, if we received an alias, we better update the buddy list */ + if (alias != NULL) { + serv_got_alias(cb->gc, yid, alias); + purple_debug_info("yahoo","Fetched alias '%s' (%s)\n",alias,id); + } else if (b->alias != alias && strcmp(b->alias, "") != 0) { + /* Or if we have an alias that Yahoo doesn't, send it up */ + yahoo_update_alias(cb->gc, yid, b->alias); + purple_debug_info("yahoo","Sent alias '%s'\n", b->alias); + } + } else { + purple_debug_info("yahoo", "Bizarre, received alias for %s, but they are not on your list...\n", yid); + } + } + } + xmlnode_free(contacts); + } + g_free(cb->id); + g_free(cb); +} + +void +yahoo_fetch_aliases(PurpleConnection *gc) +{ + struct yahoo_data *yd = gc->proto_data; + struct callback_data *cb; + const char *url = YAHOO_ALIAS_FETCH_URL; + char *request, *webpage, *webaddress; + PurpleUtilFetchUrlData *url_data; + + /* Using callback_data so I have access to gc in the callback function */ + cb = g_new0(struct callback_data, 1); + cb->gc = gc; + + /* Build all the info to make the web request */ + purple_url_parse(url, &webaddress, NULL, &webpage, NULL, NULL); + request = g_strdup_printf("GET /%s HTTP/1.1\r\n" + "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n" + "Cookie: T=%s; Y=%s\r\n" + "Host: %s\r\n" + "Cache-Control: no-cache\r\n\r\n", + webpage, yd->cookie_t,yd->cookie_y, webaddress); + + /* We have a URL and some header information, let's connect and get some aliases */ + url_data = purple_util_fetch_url_request(url, FALSE, NULL, TRUE, request, FALSE, yahoo_fetch_aliases_cb, cb); + if (url_data != NULL) { + yd->url_datas = g_slist_prepend(yd->url_datas, url_data); + } + + g_free(webaddress); + g_free(webpage); + g_free(request); +} + +/************************************************************************** + * Alias Update Functions + **************************************************************************/ + +static void +yahoo_update_alias_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data,const gchar *url_text, size_t len, const gchar *error_message) +{ + xmlnode *node, *result; + struct callback_data *cb = user_data; + PurpleConnection *gc = cb->gc; + struct yahoo_data *yd; + + yd = gc->proto_data; + yd->url_datas = g_slist_remove(yd->url_datas, url_data); + + if (len == 0 || error_message != NULL) { + purple_debug_info("yahoo", "Error updating alias: %s\n", + error_message ? error_message : ""); + g_free(cb->id); + g_free(cb); + return; + } + + result = xmlnode_from_str(url_text, -1); + + purple_debug_info("yahoo", "ID: %s, Return data: %s\n",cb->id, url_text); + + if (result == NULL) { + purple_debug_error("yahoo","Alias update failed: Badly formed response\n"); + g_free(cb->id); + g_free(cb); + return; + } + + if ((node = xmlnode_get_child(result, "ct"))) { + if (g_ascii_strncasecmp(xmlnode_get_attrib(node, "id"), cb->id, strlen(cb->id))==0) + purple_debug_info("yahoo", "Alias update succeeded\n"); + else + purple_debug_error("yahoo", "Alias update failed (Contact record return mismatch)\n"); + } else { + purple_debug_info("yahoo", "Alias update failed (No contact record returned)\n"); + } + + g_free(cb->id); + g_free(cb); + xmlnode_free(result); +} + +void +yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias) +{ + struct yahoo_data *yd; + struct YahooUser *yu; + char *content, *url, *request, *webpage, *webaddress, *strtmp; + int inttmp; + struct callback_data *cb; + PurpleBuddy *buddy; + PurpleUtilFetchUrlData *url_data; + + g_return_if_fail(alias!= NULL); + g_return_if_fail(who!=NULL); + g_return_if_fail(gc!=NULL); + + purple_debug_info("yahoo", "Sending '%s' as new alias for user '%s'.\n",alias, who); + + buddy = purple_find_buddy(gc->account, who); + if (buddy == NULL || buddy->proto_data == NULL) { + purple_debug_info("yahoo", "Missing proto_data (get_yahoo_aliases must have failed), bailing out\n"); + return; + } + + yd = gc->proto_data; + yu = buddy->proto_data; + + /* Using callback_data so I have access to gc in the callback function */ + cb = g_new0(struct callback_data, 1); + cb->id = g_strdup(yu->id); + cb->gc = gc; + + /* Build all the info to make the web request */ + url = g_strdup(YAHOO_ALIAS_UPDATE_URL); + purple_url_parse(url, &webaddress, &inttmp, &webpage, &strtmp, &strtmp); + + content = g_strdup_printf("<?xml version=\"1.0\" encoding=\"utf-8\"?><ab k=\"%s\" cc=\"1\">\n" + "<ct e=\"1\" yi='%s' id='%s' nn='%s' pr='0' />\n</ab>\r\n", + gc->account->username, who, yu->id, g_markup_escape_text(alias, strlen(alias))); + + request = g_strdup_printf("POST /%s HTTP/1.1\r\n" + "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n" + "Cookie: T=%s; Y=%s\r\n" + "Host: %s\r\n" + "Content-Length: %" G_GSIZE_FORMAT "\r\n" + "Cache-Control: no-cache\r\n\r\n" + "%s", + webpage, yd->cookie_t,yd->cookie_y, webaddress, + strlen(content), content); + + /* We have a URL and some header information, let's connect and update the alias */ + url_data = purple_util_fetch_url_request(url, FALSE, NULL, TRUE, request, FALSE, yahoo_update_alias_cb, cb); + if (url_data != NULL) { + yd->url_datas = g_slist_prepend(yd->url_datas, url_data); + } + + g_free(content); + g_free(url); + g_free(request); +} + diff --git a/libpurple/protocols/yahoo/yahoo_packet.c b/libpurple/protocols/yahoo/yahoo_packet.c index 14d0ec9241..32a81ea3bc 100644 --- a/libpurple/protocols/yahoo/yahoo_packet.c +++ b/libpurple/protocols/yahoo/yahoo_packet.c @@ -174,8 +174,7 @@ void yahoo_packet_read(struct yahoo_packet *pkt, const guchar *data, int len) } if (accept) { - /* TODO: strstr() should not be used here because data isn't NULL terminated */ - delimiter = (const guchar *)strstr((char *)&data[pos], "\xc0\x80"); + delimiter = (const guchar *)g_strstr_len((const char *)&data[pos], len - pos, "\xc0\x80"); if (delimiter == NULL) { /* Malformed packet! (It doesn't end in 0xc0 0x80) */ @@ -304,7 +303,8 @@ yahoo_packet_send_can_write(gpointer data, gint source, PurpleInputCondition con return; else if (ret < 0) { /* TODO: what to do here - do we really have to disconnect? */ - purple_connection_error(yd->gc, _("Write Error")); + purple_connection_error_reason(yd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + _("Write Error")); return; } diff --git a/libpurple/protocols/yahoo/ycht.c b/libpurple/protocols/yahoo/ycht.c index da5225dcde..17722dd0e1 100644 --- a/libpurple/protocols/yahoo/ycht.c +++ b/libpurple/protocols/yahoo/ycht.c @@ -285,7 +285,8 @@ static void ycht_packet_send_write_cb(gpointer data, gint source, PurpleInputCon else if (ret <= 0) { /* TODO: error handling */ /* - purple_connection_error(purple_account_get_connection(irc->account), + purple_connection_error_reason(purple_account_get_connection(irc->account), + PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Server has disconnected")); */ return; @@ -473,7 +474,7 @@ static void ycht_pending(gpointer data, gint source, PurpleInputCondition cond) return; tmp = g_strdup_printf(_("Lost connection with server\n%s"), - strerror(errno)); + g_strerror(errno)); ycht_connection_error(ycht, tmp); g_free(tmp); return; |