Migrate certificates, icons, logs to XDG dirs
[pidgin-git.git] / libpurple / protocols / yahoo / yahoo_aliases.c
blobce728c462e7b4b58c48aec37e4dfcef21292cdd8
1 /*
2 * purple
4 * Purple is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
6 * source distribution.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
25 #include "internal.h"
27 #include "account.h"
28 #include "accountopt.h"
29 #include "buddylist.h"
30 #include "debug.h"
31 #include "http.h"
32 #include "util.h"
33 #include "request.h"
34 #include "version.h"
35 #include "ymsg.h"
36 #include "yahoo_aliases.h"
37 #include "yahoo_friend.h"
38 #include "yahoo_packet.h"
40 /* I hate hardcoding this stuff, but Yahoo never sends us anything to use. Someone in the know may be able to tweak this URL */
41 #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=" YAHOO_CLIENT_VERSION "&useutf8=1&legenc=codepage-1252"
42 #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"
44 void yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias);
46 /**
47 * Stuff we want passed to the callback function
49 struct callback_data {
50 PurpleConnection *gc;
51 gchar *id;
52 gchar *who;
55 void yahoo_personal_details_reset(YahooPersonalDetails *ypd, gboolean all)
57 if (all)
58 g_free(ypd->id);
59 g_free(ypd->names.first);
60 g_free(ypd->names.last);
61 g_free(ypd->names.middle);
62 g_free(ypd->names.nick);
63 g_free(ypd->phone.work);
64 g_free(ypd->phone.home);
65 g_free(ypd->phone.mobile);
68 /**************************************************************************
69 * Alias Fetch Functions
70 **************************************************************************/
72 static void
73 yahoo_fetch_aliases_cb(PurpleHttpConnection *http_conn,
74 PurpleHttpResponse *response, gpointer _unused)
76 PurpleConnection *gc =
77 purple_http_conn_get_purple_connection(http_conn);
78 YahooData *yd = purple_connection_get_protocol_data(gc);
80 if (!purple_http_response_is_successful(response)) {
81 purple_debug_info("yahoo", "yahoo_fetch_aliases_cb error: %s\n",
82 purple_http_response_get_error(response));
83 } else {
84 gchar *full_name, *nick_name;
85 const gchar *xml_raw;
86 const char *yid, *id, *fn, *ln, *nn, *alias, *mn;
87 const char *hp, *wp, *mo;
88 YahooFriend *f;
89 PurpleBuddy *b;
90 PurpleXmlNode *item, *contacts;
91 PurpleAccount *account;
92 size_t len;
94 account = purple_connection_get_account(gc);
95 /* Put our web response into a PurpleXmlNode for easy management */
96 xml_raw = purple_http_response_get_data(response, &len);
97 contacts = purple_xmlnode_from_str(xml_raw, -1);
99 if (purple_debug_is_verbose()) {
100 purple_debug_misc("yahoo",
101 "yahoo_fetch_aliases_cb xml:[%s]\n", xml_raw);
104 if (contacts == NULL) {
105 purple_debug_error("yahoo", "Badly formed Alias XML\n");
106 return;
108 purple_debug_info("yahoo", "Fetched %" G_GSIZE_FORMAT
109 " bytes of alias data\n", len);
111 /* Loop around and around and around until we have gone through all the received aliases */
112 for(item = purple_xmlnode_get_child(contacts, "ct"); item; item = purple_xmlnode_get_next_twin(item)) {
113 /* Yahoo replies with two types of contact (ct) record, we are only interested in the alias ones */
114 if ((yid = purple_xmlnode_get_attrib(item, "yi"))) {
115 YahooPersonalDetails *ypd = NULL;
116 /* Grab all the bits of information we can */
117 fn = purple_xmlnode_get_attrib(item, "fn");
118 ln = purple_xmlnode_get_attrib(item, "ln");
119 nn = purple_xmlnode_get_attrib(item, "nn");
120 mn = purple_xmlnode_get_attrib(item, "mn");
121 id = purple_xmlnode_get_attrib(item, "id");
123 hp = purple_xmlnode_get_attrib(item, "hp");
124 wp = purple_xmlnode_get_attrib(item, "wp");
125 mo = purple_xmlnode_get_attrib(item, "mo");
127 full_name = nick_name = NULL;
128 alias = NULL;
130 /* Yahoo stores first and last names separately, lets put them together into a full name */
131 full_name = g_strstrip(g_strdup_printf("%s %s", (fn != NULL ? fn : "") , (ln != NULL ? ln : "")));
132 nick_name = (nn != NULL ? g_strstrip(g_strdup(nn)) : NULL);
134 if (nick_name != NULL)
135 alias = nick_name; /* If we have a nickname from Yahoo, let's use it */
136 else if (*full_name != '\0')
137 alias = full_name; /* If no Yahoo nickname, we can use the full_name created above */
139 /* Find the local buddy that matches */
140 f = yahoo_friend_find(gc, yid);
141 b = purple_blist_find_buddy(account, yid);
143 /* If we don't find a matching buddy, ignore the alias !! */
144 if (f != NULL && b != NULL) {
145 const char *buddy_alias = purple_buddy_get_alias(b);
146 yahoo_friend_set_alias_id(f, id);
148 /* Finally, if we received an alias, we better update the buddy list */
149 if (alias != NULL) {
150 purple_serv_got_alias(gc, yid, alias);
151 purple_debug_info("yahoo", "Fetched alias '%s' (%s)\n", alias, id);
152 } else if (buddy_alias && *buddy_alias && !g_str_equal(buddy_alias, yid)) {
153 /* Or if we have an alias that Yahoo doesn't, send it up */
154 yahoo_update_alias(gc, yid, buddy_alias);
155 purple_debug_info("yahoo", "Sent updated alias '%s'\n", buddy_alias);
159 if (f != NULL)
160 ypd = &f->ypd;
161 else {
162 /* May be the alias is for the account? */
163 const char *yidn = purple_normalize(account, yid);
164 if (purple_strequal(yidn, purple_connection_get_display_name(gc))) {
165 ypd = &yd->ypd;
169 if (ypd) {
170 yahoo_personal_details_reset(ypd, TRUE);
171 ypd->id = g_strdup(id);
172 ypd->names.first = g_strdup(fn);
173 ypd->names.middle = g_strdup(mn);
174 ypd->names.last = g_strdup(ln);
175 ypd->names.nick = g_strdup(nn);
177 ypd->phone.work = g_strdup(wp);
178 ypd->phone.home = g_strdup(hp);
179 ypd->phone.mobile = g_strdup(mo);
182 g_free(full_name);
183 g_free(nick_name);
186 purple_xmlnode_free(contacts);
190 void
191 yahoo_fetch_aliases(PurpleConnection *gc)
193 YahooData *yd = purple_connection_get_protocol_data(gc);
194 PurpleHttpRequest *req;
195 PurpleHttpCookieJar *cookiejar;
197 req = purple_http_request_new(YAHOO_ALIAS_FETCH_URL);
198 /* XXX: see the other note about user-agent */
199 purple_http_request_header_set(req, "User-Agent",
200 "Mozilla/4.0 (compatible; MSIE 5.5)");
201 cookiejar = purple_http_request_get_cookie_jar(req);
202 purple_http_cookie_jar_set(cookiejar, "T", yd->cookie_t);
203 purple_http_cookie_jar_set(cookiejar, "Y", yd->cookie_y);
204 purple_http_connection_set_add(yd->http_reqs, purple_http_request(gc,
205 req, yahoo_fetch_aliases_cb, NULL));
206 purple_http_request_unref(req);
209 /**************************************************************************
210 * Alias Update Functions
211 **************************************************************************/
213 static void
214 yahoo_update_alias_cb(PurpleHttpConnection *http_conn,
215 PurpleHttpResponse *response, gpointer _cb)
217 PurpleXmlNode *node, *result;
218 struct callback_data *cb = _cb;
220 if (!purple_http_response_is_successful(response)) {
221 purple_debug_info("yahoo", "Error updating alias for %s: %s\n",
222 cb->who, purple_http_response_get_error(response));
223 g_free(cb->who);
224 g_free(cb->id);
225 g_free(cb);
226 return;
229 result = purple_xmlnode_from_str(
230 purple_http_response_get_data(response, NULL), -1);
232 if (result == NULL) {
233 purple_debug_error("yahoo", "Alias update for %s failed: Badly formed response\n",
234 cb->who);
235 g_free(cb->who);
236 g_free(cb->id);
237 g_free(cb);
238 return;
241 if ((node = purple_xmlnode_get_child(result, "ct"))) {
242 if (cb->id == NULL) {
243 const char *new_id = purple_xmlnode_get_attrib(node, "id");
244 if (new_id != NULL) {
245 /* We now have an addressbook id for the friend; we should save it */
246 YahooFriend *f = yahoo_friend_find(cb->gc, cb->who);
248 purple_debug_info("yahoo", "Alias creation for %s succeeded\n", cb->who);
250 if (f)
251 yahoo_friend_set_alias_id(f, new_id);
252 else
253 purple_debug_error("yahoo", "Missing YahooFriend. Unable to store new addressbook id.\n");
254 } else
255 purple_debug_error("yahoo", "Missing new addressbook id in add response for %s (weird).\n",
256 cb->who);
257 } else {
258 if (g_ascii_strncasecmp(purple_xmlnode_get_attrib(node, "id"), cb->id, strlen(cb->id))==0)
259 purple_debug_info("yahoo", "Alias update for %s succeeded\n", cb->who);
260 else
261 purple_debug_error("yahoo", "Alias update for %s failed (Contact record return mismatch)\n",
262 cb->who);
264 } else
265 purple_debug_info("yahoo", "Alias update for %s failed (No contact record returned)\n", cb->who);
267 g_free(cb->who);
268 g_free(cb->id);
269 g_free(cb);
270 purple_xmlnode_free(result);
273 void
274 yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias)
276 PurpleHttpRequest *req;
277 PurpleHttpCookieJar *cookiejar;
278 YahooData *yd;
279 gchar *content, *escaped_alias;
280 struct callback_data *cb;
281 YahooFriend *f;
283 g_return_if_fail(who != NULL);
284 g_return_if_fail(gc != NULL);
286 if (alias == NULL)
287 alias = "";
289 f = yahoo_friend_find(gc, who);
290 if (f == NULL) {
291 purple_debug_error("yahoo", "Missing YahooFriend. Unable to set server alias.\n");
292 return;
295 yd = purple_connection_get_protocol_data(gc);
297 /* Using callback_data so I have access to gc in the callback function */
298 cb = g_new0(struct callback_data, 1);
299 cb->who = g_strdup(who);
300 cb->id = g_strdup(yahoo_friend_get_alias_id(f));
301 cb->gc = gc;
303 escaped_alias = g_markup_escape_text(alias, -1);
305 if (cb->id == NULL) {
306 /* No id for this buddy, so create an address book entry */
307 purple_debug_info("yahoo", "Creating '%s' as new alias for user '%s'\n", alias, who);
309 content = g_strdup_printf("<?xml version=\"1.0\" encoding=\"utf-8\"?><ab k=\"%s\" cc=\"9\">\n"
310 "<ct a=\"1\" yi='%s' nn='%s' />\n</ab>\r\n",
311 purple_account_get_username(purple_connection_get_account(gc)),
312 who, escaped_alias);
313 g_free(escaped_alias);
314 } else {
315 purple_debug_info("yahoo", "Updating '%s' as new alias for user '%s'\n", alias, who);
317 content = g_strdup_printf("<?xml version=\"1.0\" encoding=\"utf-8\"?><ab k=\"%s\" cc=\"1\">\n"
318 "<ct e=\"1\" yi='%s' id='%s' nn='%s' pr='0' />\n</ab>\r\n",
319 purple_account_get_username(purple_connection_get_account(gc)),
320 who, cb->id, escaped_alias);
321 g_free(escaped_alias);
324 req = purple_http_request_new(YAHOO_ALIAS_UPDATE_URL);
325 purple_http_request_set_method(req, "POST");
326 /* XXX: We get rs="ERROR:-100:No Login", when we set
327 * YAHOO_CLIENT_USERAGENT (Mozilla/5.0) here.
329 purple_http_request_header_set(req, "User-Agent",
330 "Mozilla/4.0 (compatible; MSIE 5.5)");
331 cookiejar = purple_http_request_get_cookie_jar(req);
332 purple_http_cookie_jar_set(cookiejar, "T", yd->cookie_t);
333 purple_http_cookie_jar_set(cookiejar, "Y", yd->cookie_y);
334 purple_http_request_set_contents(req, content, -1);
335 purple_http_connection_set_add(yd->http_reqs, purple_http_request(gc,
336 req, yahoo_update_alias_cb, cb));
337 purple_http_request_unref(req);
339 g_free(content);
343 /**************************************************************************
344 * User Info Update Functions
345 **************************************************************************/
347 #if 0
348 /* This block of code can be used to send our contact details to
349 * everyone in the buddylist. But with the official messenger,
350 * doing this pops a conversation window at the receiver's end,
351 * which is stupid, and thus not really surprising. */
353 struct yahoo_userinfo {
354 YahooData *yd;
355 char *xml;
358 static void
359 yahoo_send_userinfo_to_user(struct yahoo_userinfo *yui, const char *who)
361 struct yahoo_packet *pkt;
362 PurpleConnection *gc;
364 gc = yui->yd->gc;
365 pkt = yahoo_packet_new(YAHOO_SERVICE_CONTACT_DETAILS, 0, 0);
366 yahoo_packet_hash(pkt, "siisis",
367 1, purple_connection_get_display_name(gc),
368 13, 1, /* This creates a conversation window in the official client */
369 302, 5,
370 5, who,
371 303, 5,
372 280, yui->xml);
373 yahoo_packet_send_and_free(pkt, yui->yd);
376 static void
377 yahoo_send_userinfo_foreach(gpointer key, gpointer value, gpointer data)
379 const char *who = key;
380 YahooFriend *f = value;
382 if (f->status != YAHOO_STATUS_OFFLINE) {
383 yahoo_send_userinfo_to_user(data, who);
387 static void
388 yahoo_sent_userinfo_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, size_t len, const gchar *error_message)
390 struct yahoo_userinfo *yui = user_data;
391 yahoo_fetch_aliases_cb(url_data, yui->yd->gc, url_text, len, error_message);
392 g_hash_table_foreach(yui->yd->friends, yahoo_send_userinfo_foreach, yui);
393 g_free(yui->xml);
394 g_free(yui);
396 #endif
398 static void
399 yahoo_set_userinfo_cb(PurpleConnection *gc, PurpleRequestFields *fields)
401 PurpleHttpRequest *req;
402 PurpleHttpCookieJar *cookiejar;
404 PurpleXmlNode *node = purple_xmlnode_new("ab");
405 PurpleXmlNode *ct = purple_xmlnode_new_child(node, "ct");
406 YahooData *yd = purple_connection_get_protocol_data(gc);
407 char *content;
408 int len;
409 int i;
410 char * yfields[] = { "fn", "ln", "nn", "mn", "hp", "wp", "mo", NULL };
412 purple_xmlnode_set_attrib(node, "k", purple_connection_get_display_name(gc));
413 purple_xmlnode_set_attrib(node, "cc", "1"); /* XXX: ? */
415 purple_xmlnode_set_attrib(ct, "e", "1");
416 purple_xmlnode_set_attrib(ct, "yi", purple_request_fields_get_string(fields, "yname"));
417 purple_xmlnode_set_attrib(ct, "id", purple_request_fields_get_string(fields, "yid"));
418 purple_xmlnode_set_attrib(ct, "pr", "0");
420 for (i = 0; yfields[i]; i++) {
421 const char *v = purple_request_fields_get_string(fields, yfields[i]);
422 purple_xmlnode_set_attrib(ct, yfields[i], v ? v : "");
425 content = purple_xmlnode_to_formatted_str(node, &len);
426 purple_xmlnode_free(node);
428 #if 0
430 /* This is if we wanted to send our contact details to everyone
431 * in the buddylist. But this cannot be done now, because in the
432 * official messenger, doing this pops a conversation window at
433 * the receiver's end, which is stupid, and thus not really
434 * surprising. */
435 struct yahoo_userinfo *ui = g_new(struct yahoo_userinfo, 1);
436 node = purple_xmlnode_new("contact");
438 for (i = 0; yfields[i]; i++) {
439 const char *v = purple_request_fields_get_string(fields, yfields[i]);
440 if (v) {
441 PurpleXmlNode *nd = purple_xmlnode_new_child(node, yfields[i]);
442 purple_xmlnode_insert_data(nd, v, -1);
446 ui->yd = yd;
447 ui->xml = purple_xmlnode_to_str(node, NULL);
448 purple_xmlnode_free(node);
450 #endif
452 req = purple_http_request_new(YAHOO_USERINFO_URL);
453 purple_http_request_set_method(req, "POST");
454 /* XXX: see the previous comment for user-agent */
455 purple_http_request_header_set(req, "User-Agent",
456 "Mozilla/4.0 (compatible; MSIE 5.5)");
457 cookiejar = purple_http_request_get_cookie_jar(req);
458 purple_http_cookie_jar_set(cookiejar, "T", yd->cookie_t);
459 purple_http_cookie_jar_set(cookiejar, "Y", yd->cookie_y);
460 purple_http_request_set_contents(req, content, -1);
461 purple_http_connection_set_add(yd->http_reqs, purple_http_request(gc,
462 req, yahoo_fetch_aliases_cb, NULL));
463 purple_http_request_unref(req);
465 g_free(content);
468 static PurpleRequestFields *
469 request_fields_from_personal_details(YahooPersonalDetails *ypd, const char *id)
471 PurpleRequestFields *fields;
472 PurpleRequestFieldGroup *group;
473 PurpleRequestField *field;
474 int i;
475 struct {
476 char *id;
477 char *text;
478 char *value;
479 } yfields[] = {
480 {"fn", N_("First Name"), ypd->names.first},
481 {"ln", N_("Last Name"), ypd->names.last},
482 {"nn", N_("Nickname"), ypd->names.nick},
483 {"mn", N_("Middle Name"), ypd->names.middle},
484 {"hp", N_("Home Phone Number"), ypd->phone.home},
485 {"wp", N_("Work Phone Number"), ypd->phone.work},
486 {"mo", N_("Mobile Phone Number"), ypd->phone.mobile},
487 {NULL, NULL, NULL}
490 if (ypd->id == NULL) {
491 purple_debug_error("yahoo",
492 "request_fields_from_personal_details:"
493 "ypd->id == NULL (it doesn't seems to work)\n");
494 return NULL;
497 fields = purple_request_fields_new();
498 group = purple_request_field_group_new(NULL);
499 purple_request_fields_add_group(fields, group);
501 field = purple_request_field_string_new("yname", "", id, FALSE);
502 purple_request_field_set_visible(field, FALSE);
503 purple_request_field_group_add_field(group, field);
505 field = purple_request_field_string_new("yid", "", ypd->id, FALSE);
506 purple_request_field_set_visible(field, FALSE);
507 purple_request_field_group_add_field(group, field);
509 for (i = 0; yfields[i].id; i++) {
510 field = purple_request_field_string_new(yfields[i].id, _(yfields[i].text),
511 yfields[i].value, FALSE);
512 purple_request_field_group_add_field(group, field);
515 return fields;
518 void yahoo_set_userinfo_for_buddy(PurpleConnection *gc, PurpleBuddy *buddy)
520 PurpleRequestFields *fields;
521 YahooFriend *f;
522 const char *name;
524 name = purple_buddy_get_name(buddy);
525 f = yahoo_friend_find(gc, name);
526 if (!f)
527 return;
529 fields = request_fields_from_personal_details(&f->ypd, name);
530 if (fields == NULL)
531 return;
532 purple_request_fields(gc, NULL, _("Set User Info"), NULL, fields,
533 _("OK"), G_CALLBACK(yahoo_set_userinfo_cb),
534 _("Cancel"), NULL,
535 purple_request_cpar_from_connection(gc), gc);
538 void yahoo_set_userinfo(PurpleConnection *gc)
540 YahooData *yd = purple_connection_get_protocol_data(gc);
541 PurpleRequestFields *fields = request_fields_from_personal_details(&yd->ypd,
542 purple_connection_get_display_name(gc));
543 if (fields == NULL)
544 return;
545 purple_request_fields(gc, NULL, _("Set User Info"), NULL, fields,
546 _("OK"), G_CALLBACK(yahoo_set_userinfo_cb),
547 _("Cancel"), NULL,
548 purple_request_cpar_from_connection(gc), gc);
551 static gboolean
552 parse_contact_details(YahooData *yd, const char *who, const char *xml)
554 PurpleXmlNode *node, *nd;
555 YahooFriend *f;
556 char *yid;
558 node = purple_xmlnode_from_str(xml, -1);
559 if (!node) {
560 purple_debug_info("yahoo", "Received malformed XML for contact details from '%s':\n%s\n",
561 who, xml);
562 return FALSE;
565 nd = purple_xmlnode_get_child(node, "yi");
566 if (!nd || !(yid = purple_xmlnode_get_data(nd))) {
567 purple_xmlnode_free(node);
568 return FALSE;
571 if (!purple_strequal(yid, who)) {
572 /* The user may not want to set the contact details about folks in the buddylist
573 to what some random dude might have sent. So it would be good if we popped
574 up a prompt requiring the user to confirm the details before we set them.
575 However, someone could send details about hundreds of users at the same time,
576 which would make things really bad. So for now, until we have a better way of
577 dealing with this, ignore this details. */
578 purple_debug_info("yahoo", "Ignoring contact details sent by %s about %s\n",
579 who, yid);
580 g_free(yid);
581 purple_xmlnode_free(node);
582 return FALSE;
585 f = yahoo_friend_find(yd->gc, yid);
586 if (!f) {
587 g_free(yid);
588 purple_xmlnode_free(node);
589 return FALSE;
590 } else {
591 int i;
592 YahooPersonalDetails *ypd = &f->ypd;
593 char *alias = NULL;
594 struct {
595 char *id;
596 char **field;
597 } details[] = {
598 {"fn", &ypd->names.first},
599 {"mn", &ypd->names.middle},
600 {"ln", &ypd->names.last},
601 {"nn", &ypd->names.nick},
602 {"wp", &ypd->phone.work},
603 {"hp", &ypd->phone.home},
604 {"mo", &ypd->phone.mobile},
605 {NULL, NULL}
608 yahoo_personal_details_reset(ypd, FALSE);
610 for (i = 0; details[i].id; i++) {
611 nd = purple_xmlnode_get_child(node, details[i].id);
612 *details[i].field = nd ? purple_xmlnode_get_data(nd) : NULL;
615 if (ypd->names.nick)
616 alias = ypd->names.nick;
617 else if (ypd->names.first || ypd->names.last) {
618 alias = g_strstrip(g_strdup_printf("%s %s",
619 ypd->names.first ? ypd->names.first : "",
620 ypd->names.last ? ypd->names.last : ""));
623 if (alias) {
624 purple_serv_got_alias(yd->gc, yid, alias);
625 if (alias != ypd->names.nick)
626 g_free(alias);
630 purple_xmlnode_free(node);
631 g_free(yid);
632 return TRUE;
635 void yahoo_process_contact_details(PurpleConnection *gc, struct yahoo_packet *pkt)
637 GSList *l = pkt->hash;
638 const char *who = NULL, *xml = NULL;
639 YahooData *yd = purple_connection_get_protocol_data(gc);
641 for (; l; l = l->next) {
642 struct yahoo_pair *pair = l->data;
643 switch (pair->key) {
644 case 4:
645 if (g_utf8_validate(pair->value, -1, NULL)) {
646 /* This is the person who sent us the details.
647 But not necessarily about himself. */
648 who = pair->value;
649 } else {
650 purple_debug_warning("yahoo", "yahoo_process_contact_details "
651 "got non-UTF-8 string for key %d\n", pair->key);
653 break;
654 case 5:
655 break;
656 case 13:
657 /* This is '1' if 'who' is sending the contact details about herself,
658 '0' if 'who' is sending the contact details she has about buddies
659 in her list. However, in all cases, the xml in key 280 always seems
660 to contain the yid of the person, so we may as well ignore this field
661 and look into the xml instead to see who the information is about. */
662 break;
663 case 280:
664 if (g_utf8_validate(pair->value, -1, NULL)) {
665 xml = pair->value;
666 parse_contact_details(yd, who, xml);
667 } else {
668 purple_debug_warning("yahoo", "yahoo_process_contact_details "
669 "got non-UTF-8 string for key %d\n", pair->key);
671 break;