comparison libpurple/protocols/jabber/buddy.c @ 25237:401f548e3544

propagate from branch 'im.pidgin.pidgin' (head df6eba32e5b6b34d7483cbfb7e9f2e4c836ac35f) to branch 'org.darkrain42.pidgin.buddy-add' (head 6831808999a270f8c1a128c7430a73d3dc0bfae2)
author Paul Aurich <paul@darkrain42.org>
date Sun, 21 Dec 2008 18:32:37 +0000
parents 61e0924de04a
children 9100b9176a16 c07b0aa88a35 65cfc59858cf
comparison
equal deleted inserted replaced
25172:125cac3e24ee 25237:401f548e3544
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
19 * 19 *
20 */ 20 */
21 #include "internal.h" 21 #include "internal.h"
22 #include "cipher.h"
23 #include "debug.h" 22 #include "debug.h"
24 #include "imgstore.h" 23 #include "imgstore.h"
25 #include "prpl.h" 24 #include "prpl.h"
26 #include "notify.h" 25 #include "notify.h"
27 #include "request.h" 26 #include "request.h"
449 if ((img = purple_buddy_icons_find_account_icon(gc->account))) { 448 if ((img = purple_buddy_icons_find_account_icon(gc->account))) {
450 gconstpointer avatar_data; 449 gconstpointer avatar_data;
451 gsize avatar_len; 450 gsize avatar_len;
452 xmlnode *photo, *binval, *type; 451 xmlnode *photo, *binval, *type;
453 gchar *enc; 452 gchar *enc;
454 int i;
455 unsigned char hashval[20];
456 char *p, hash[41];
457 453
458 if(!vc_node) { 454 if(!vc_node) {
459 vc_node = xmlnode_new("vCard"); 455 vc_node = xmlnode_new("vCard");
460 for(tag_attr = vcard_tag_attr_list; tag_attr->attr != NULL; ++tag_attr) 456 for(tag_attr = vcard_tag_attr_list; tag_attr->attr != NULL; ++tag_attr)
461 xmlnode_set_attrib(vc_node, tag_attr->attr, tag_attr->value); 457 xmlnode_set_attrib(vc_node, tag_attr->attr, tag_attr->value);
471 type = xmlnode_new_child(photo, "TYPE"); 467 type = xmlnode_new_child(photo, "TYPE");
472 xmlnode_insert_data(type, "image/png", -1); 468 xmlnode_insert_data(type, "image/png", -1);
473 binval = xmlnode_new_child(photo, "BINVAL"); 469 binval = xmlnode_new_child(photo, "BINVAL");
474 enc = purple_base64_encode(avatar_data, avatar_len); 470 enc = purple_base64_encode(avatar_data, avatar_len);
475 471
476 purple_cipher_digest_region("sha1", avatar_data, 472 js->avatar_hash = jabber_calculate_data_sha1sum(avatar_data, avatar_len);
477 avatar_len, sizeof(hashval),
478 hashval, NULL);
479
480 purple_imgstore_unref(img);
481
482 p = hash;
483 for(i=0; i<20; i++, p+=2)
484 snprintf(p, 3, "%02x", hashval[i]);
485 js->avatar_hash = g_strdup(hash);
486 473
487 xmlnode_insert_data(binval, enc, -1); 474 xmlnode_insert_data(binval, enc, -1);
488 g_free(enc); 475 g_free(enc);
489 } 476 }
490 477
543 guint32 height = ntohl(png->ihdr.height); 530 guint32 height = ntohl(png->ihdr.height);
544 xmlnode *publish, *item, *data, *metadata, *info; 531 xmlnode *publish, *item, *data, *metadata, *info;
545 char *lengthstring, *widthstring, *heightstring; 532 char *lengthstring, *widthstring, *heightstring;
546 533
547 /* compute the sha1 hash */ 534 /* compute the sha1 hash */
548 PurpleCipherContext *ctx; 535 char *hash = jabber_calculate_data_sha1sum(purple_imgstore_get_data(img), purple_imgstore_get_size(img));
549 unsigned char digest[20];
550 char *hash;
551 char *base64avatar; 536 char *base64avatar;
552
553 ctx = purple_cipher_context_new_by_name("sha1", NULL);
554 purple_cipher_context_append(ctx, purple_imgstore_get_data(img), purple_imgstore_get_size(img));
555 purple_cipher_context_digest(ctx, sizeof(digest), digest, NULL);
556 purple_cipher_context_destroy(ctx);
557
558 /* convert digest to a string */
559 hash = g_strdup_printf("%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x",digest[0],digest[1],digest[2],digest[3],digest[4],digest[5],digest[6],digest[7],digest[8],digest[9],digest[10],digest[11],digest[12],digest[13],digest[14],digest[15],digest[16],digest[17],digest[18],digest[19]);
560 537
561 publish = xmlnode_new("publish"); 538 publish = xmlnode_new("publish");
562 xmlnode_set_attrib(publish,"node",AVATARNAMESPACEDATA); 539 xmlnode_set_attrib(publish,"node",AVATARNAMESPACEDATA);
563 540
564 item = xmlnode_new_child(publish, "item"); 541 item = xmlnode_new_child(publish, "item");
1405 if( ((binval = xmlnode_get_child(child, "BINVAL")) && 1382 if( ((binval = xmlnode_get_child(child, "BINVAL")) &&
1406 (bintext = xmlnode_get_data(binval))) || 1383 (bintext = xmlnode_get_data(binval))) ||
1407 (bintext = xmlnode_get_data(child))) { 1384 (bintext = xmlnode_get_data(child))) {
1408 gsize size; 1385 gsize size;
1409 guchar *data; 1386 guchar *data;
1410 int i;
1411 unsigned char hashval[20];
1412 char *p, hash[41];
1413 gboolean photo = (strcmp(child->name, "PHOTO") == 0); 1387 gboolean photo = (strcmp(child->name, "PHOTO") == 0);
1414 1388
1415 data = purple_base64_decode(bintext, &size); 1389 data = purple_base64_decode(bintext, &size);
1416 if (data) { 1390 if (data) {
1417 char *img_text; 1391 char *img_text;
1392 char *hash;
1418 1393
1419 jbi->vcard_imgids = g_slist_prepend(jbi->vcard_imgids, GINT_TO_POINTER(purple_imgstore_add_with_id(g_memdup(data, size), size, "logo.png"))); 1394 jbi->vcard_imgids = g_slist_prepend(jbi->vcard_imgids, GINT_TO_POINTER(purple_imgstore_add_with_id(g_memdup(data, size), size, "logo.png")));
1420 img_text = g_strdup_printf("<img id='%d'>", GPOINTER_TO_INT(jbi->vcard_imgids->data)); 1395 img_text = g_strdup_printf("<img id='%d'>", GPOINTER_TO_INT(jbi->vcard_imgids->data));
1421 1396
1422 purple_notify_user_info_add_pair(user_info, (photo ? _("Photo") : _("Logo")), img_text); 1397 purple_notify_user_info_add_pair(user_info, (photo ? _("Photo") : _("Logo")), img_text);
1423 1398
1424 purple_cipher_digest_region("sha1", (guchar *)data, size, 1399 hash = jabber_calculate_data_sha1sum(data, size);
1425 sizeof(hashval), hashval, NULL);
1426 p = hash;
1427 for(i=0; i<20; i++, p+=2)
1428 snprintf(p, 3, "%02x", hashval[i]);
1429
1430 purple_buddy_icons_set_for_user(js->gc->account, bare_jid, 1400 purple_buddy_icons_set_for_user(js->gc->account, bare_jid,
1431 data, size, hash); 1401 data, size, hash);
1432 g_free(bintext); 1402 g_free(hash);
1433 g_free(img_text); 1403 g_free(img_text);
1434 } 1404 }
1405 g_free(bintext);
1435 } 1406 }
1436 } 1407 }
1437 g_free(text); 1408 g_free(text);
1438 } 1409 }
1439 } 1410 }
1523 /* check if we have received a stop */ 1494 /* check if we have received a stop */
1524 if(xmlnode_get_child(metadata, "stop")) { 1495 if(xmlnode_get_child(metadata, "stop")) {
1525 purple_buddy_icons_set_for_user(purple_connection_get_account(js->gc), from, NULL, 0, NULL); 1496 purple_buddy_icons_set_for_user(purple_connection_get_account(js->gc), from, NULL, 0, NULL);
1526 } else { 1497 } else {
1527 xmlnode *info, *goodinfo = NULL; 1498 xmlnode *info, *goodinfo = NULL;
1528 1499 gboolean has_children = FALSE;
1500
1529 /* iterate over all info nodes to get one we can use */ 1501 /* iterate over all info nodes to get one we can use */
1530 for(info = metadata->child; info; info = info->next) { 1502 for(info = metadata->child; info; info = info->next) {
1503 if(info->type == XMLNODE_TYPE_TAG)
1504 has_children = TRUE;
1531 if(info->type == XMLNODE_TYPE_TAG && !strcmp(info->name,"info")) { 1505 if(info->type == XMLNODE_TYPE_TAG && !strcmp(info->name,"info")) {
1532 const char *type = xmlnode_get_attrib(info,"type"); 1506 const char *type = xmlnode_get_attrib(info,"type");
1533 const char *id = xmlnode_get_attrib(info,"id"); 1507 const char *id = xmlnode_get_attrib(info,"id");
1534 1508
1535 if(checksum && id && !strcmp(id, checksum)) { 1509 if(checksum && id && !strcmp(id, checksum)) {
1540 /* We'll only pick the png one for now. It's a very nice image format anyways. */ 1514 /* We'll only pick the png one for now. It's a very nice image format anyways. */
1541 if(type && id && !goodinfo && !strcmp(type, "image/png")) 1515 if(type && id && !goodinfo && !strcmp(type, "image/png"))
1542 goodinfo = info; 1516 goodinfo = info;
1543 } 1517 }
1544 } 1518 }
1545 if(goodinfo) { 1519 if(has_children == FALSE) {
1520 purple_buddy_icons_set_for_user(purple_connection_get_account(js->gc), from, NULL, 0, NULL);
1521 } else if(goodinfo) {
1546 const char *url = xmlnode_get_attrib(goodinfo, "url"); 1522 const char *url = xmlnode_get_attrib(goodinfo, "url");
1547 const char *id = xmlnode_get_attrib(goodinfo,"id"); 1523 const char *id = xmlnode_get_attrib(goodinfo,"id");
1548 1524
1549 /* the avatar might either be stored in a pep node, or on a HTTP/HTTPS URL */ 1525 /* the avatar might either be stored in a pep node, or on a HTTP/HTTPS URL */
1550 if(!url) 1526 if(!url)
1800 } 1776 }
1801 1777
1802 void jabber_buddy_get_info(PurpleConnection *gc, const char *who) 1778 void jabber_buddy_get_info(PurpleConnection *gc, const char *who)
1803 { 1779 {
1804 JabberStream *js = gc->proto_data; 1780 JabberStream *js = gc->proto_data;
1805 char *bare_jid = jabber_get_bare_jid(who); 1781 JabberID *jid = jabber_id_new(who);
1806 1782
1807 if(bare_jid) { 1783 if (!jid)
1784 return;
1785
1786 if (jabber_chat_find(js, jid->node, jid->domain)) {
1787 /* For a conversation, include the resource (indicates the user). */
1788 jabber_buddy_get_info_for_jid(js, who);
1789 } else {
1790 char *bare_jid = jabber_get_bare_jid(who);
1808 jabber_buddy_get_info_for_jid(js, bare_jid); 1791 jabber_buddy_get_info_for_jid(js, bare_jid);
1809 g_free(bare_jid); 1792 g_free(bare_jid);
1810 } 1793 }
1794
1795 jabber_id_free(jid);
1811 } 1796 }
1812 1797
1813 static void jabber_buddy_set_invisibility(JabberStream *js, const char *who, 1798 static void jabber_buddy_set_invisibility(JabberStream *js, const char *who,
1814 gboolean invisible) 1799 gboolean invisible)
1815 { 1800 {