comparison libpurple/protocols/jabber/buddy.c @ 26474:8399b545925c

propagate from branch 'im.pidgin.pidgin' (head 58b2ba106e563fcd0984b9438aa427f1d61e25e9) to branch 'im.pidgin.cpw.darkrain42.xmpp.iq-handlers' (head a7d6ab07b988776e830ffb6befb18179ff46e24e)
author Paul Aurich <paul@darkrain42.org>
date Sat, 04 Apr 2009 07:08:33 +0000
parents 00870e5f2e90
children 242a8c97270b bc7fac8e2f79 7fba18b43da3 eea396f1583c b87843de7c6a
comparison
equal deleted inserted replaced
26433:c08719989149 26474:8399b545925c
153 if(!jbr) { 153 if(!jbr) {
154 jbr = g_new0(JabberBuddyResource, 1); 154 jbr = g_new0(JabberBuddyResource, 1);
155 jbr->jb = jb; 155 jbr->jb = jb;
156 jbr->name = g_strdup(resource); 156 jbr->name = g_strdup(resource);
157 jbr->capabilities = JABBER_CAP_XHTML; 157 jbr->capabilities = JABBER_CAP_XHTML;
158 jbr->tz_off = PURPLE_NO_TZ_OFF;
158 jb->resources = g_list_append(jb->resources, jbr); 159 jb->resources = g_list_append(jb->resources, jbr);
159 } 160 }
160 jbr->priority = priority; 161 jbr->priority = priority;
161 jbr->state = state; 162 jbr->state = state;
162 g_free(jbr->status); 163 g_free(jbr->status);
794 g_free(tmp); 795 g_free(tmp);
795 796
796 if(jbr->client.os) { 797 if(jbr->client.os) {
797 purple_notify_user_info_prepend_pair(user_info, _("Operating System"), jbr->client.os); 798 purple_notify_user_info_prepend_pair(user_info, _("Operating System"), jbr->client.os);
798 } 799 }
800 }
801 if (jbr && jbr->tz_off != PURPLE_NO_TZ_OFF) {
802 time_t now_t;
803 struct tm *now;
804 char *timestamp;
805 time(&now_t);
806 now_t += jbr->tz_off;
807 now = gmtime(&now_t);
808
809 timestamp = g_strdup_printf("%s %c%02d%02d", purple_time_format(now),
810 jbr->tz_off < 0 ? '-' : '+',
811 abs(jbr->tz_off / (60*60)),
812 abs((jbr->tz_off % (60*60)) / 60));
813 purple_notify_user_info_prepend_pair(user_info, _("Local Time"), timestamp);
814 g_free(timestamp);
799 } 815 }
800 if(jbir) { 816 if(jbir) {
801 if(jbir->idle_seconds > 0) { 817 if(jbir->idle_seconds > 0) {
802 char *idle = purple_str_seconds_to_string(jbir->idle_seconds); 818 char *idle = purple_str_seconds_to_string(jbir->idle_seconds);
803 purple_notify_user_info_prepend_pair(user_info, _("Idle"), idle); 819 purple_notify_user_info_prepend_pair(user_info, _("Idle"), idle);
913 feature = _("User Browsing"); 929 feature = _("User Browsing");
914 else if(!strcmp(feature, "http://jabber.org/protocol/gaming")) 930 else if(!strcmp(feature, "http://jabber.org/protocol/gaming"))
915 feature = _("User Gaming"); 931 feature = _("User Gaming");
916 else if(!strcmp(feature, "http://jabber.org/protocol/viewing")) 932 else if(!strcmp(feature, "http://jabber.org/protocol/viewing"))
917 feature = _("User Viewing"); 933 feature = _("User Viewing");
918 else if(!strcmp(feature, "urn:xmpp:ping") || !strcmp(feature, "http://www.xmpp.org/extensions/xep-0199.html#ns")) 934 else if(!strcmp(feature, "urn:xmpp:ping"))
919 feature = _("Ping"); 935 feature = _("Ping");
920 else if(!strcmp(feature, "http://www.xmpp.org/extensions/xep-0200.html#ns")) 936 else if(!strcmp(feature, "http://www.xmpp.org/extensions/xep-0200.html#ns"))
921 feature = _("Stanza Encryption"); 937 feature = _("Stanza Encryption");
922 else if(!strcmp(feature, "urn:xmpp:time")) 938 else if(!strcmp(feature, "urn:xmpp:time"))
923 feature = _("Entity Time"); 939 feature = _("Entity Time");
963 g_free(tmp); 979 g_free(tmp);
964 980
965 if(jbr->client.os) { 981 if(jbr->client.os) {
966 purple_notify_user_info_prepend_pair(user_info, _("Operating System"), jbr->client.os); 982 purple_notify_user_info_prepend_pair(user_info, _("Operating System"), jbr->client.os);
967 } 983 }
984 }
985
986 if (jbr->tz_off != PURPLE_NO_TZ_OFF) {
987 time_t now_t;
988 struct tm *now;
989 char *timestamp;
990 time(&now_t);
991 now_t += jbr->tz_off;
992 now = gmtime(&now_t);
993
994 timestamp = g_strdup_printf("%s %c%02d%02d", purple_time_format(now),
995 jbr->tz_off < 0 ? '-' : '+',
996 abs(jbr->tz_off / (60*60)),
997 abs((jbr->tz_off % (60*60)) / 60));
998 purple_notify_user_info_prepend_pair(user_info, _("Local Time"), timestamp);
999 g_free(timestamp);
968 } 1000 }
969 1001
970 if(jbr->name && (jbir = g_hash_table_lookup(jbi->resources, jbr->name))) { 1002 if(jbr->name && (jbir = g_hash_table_lookup(jbi->resources, jbr->name))) {
971 if(jbir->idle_seconds > 0) { 1003 if(jbir->idle_seconds > 0) {
972 char *idle = purple_str_seconds_to_string(jbir->idle_seconds); 1004 char *idle = purple_str_seconds_to_string(jbir->idle_seconds);
1083 feature = _("User Browsing"); 1115 feature = _("User Browsing");
1084 else if(!strcmp(feature, "http://jabber.org/protocol/gaming")) 1116 else if(!strcmp(feature, "http://jabber.org/protocol/gaming"))
1085 feature = _("User Gaming"); 1117 feature = _("User Gaming");
1086 else if(!strcmp(feature, "http://jabber.org/protocol/viewing")) 1118 else if(!strcmp(feature, "http://jabber.org/protocol/viewing"))
1087 feature = _("User Viewing"); 1119 feature = _("User Viewing");
1088 else if(!strcmp(feature, "urn:xmpp:ping") || !strcmp(feature, "http://www.xmpp.org/extensions/xep-0199.html#ns")) 1120 else if(!strcmp(feature, "urn:xmpp:ping"))
1089 feature = _("Ping"); 1121 feature = _("Ping");
1090 else if(!strcmp(feature, "http://www.xmpp.org/extensions/xep-0200.html#ns")) 1122 else if(!strcmp(feature, "http://www.xmpp.org/extensions/xep-0200.html#ns"))
1091 feature = _("Stanza Encryption"); 1123 feature = _("Stanza Encryption");
1092 else if(!strcmp(feature, "urn:xmpp:time")) 1124 else if(!strcmp(feature, "urn:xmpp:time"))
1093 feature = _("Entity Time"); 1125 feature = _("Entity Time");
1149 } 1181 }
1150 l = l->next; 1182 l = l->next;
1151 } 1183 }
1152 } 1184 }
1153 1185
1154 static void jabber_vcard_save_mine(JabberStream *js, xmlnode *packet, gpointer data) 1186 static void jabber_vcard_save_mine(JabberStream *js, const char *from,
1187 JabberIqType type, const char *id,
1188 xmlnode *packet, gpointer data)
1155 { 1189 {
1156 xmlnode *vcard; 1190 xmlnode *vcard;
1157 char *txt; 1191 char *txt;
1158 PurpleStoredImage *img; 1192 PurpleStoredImage *img;
1193
1194 if (type == JABBER_IQ_ERROR) {
1195 purple_debug_warning("jabber", "Server returned error while retrieving vCard");
1196 return;
1197 }
1159 1198
1160 if((vcard = xmlnode_get_child(packet, "vCard")) || 1199 if((vcard = xmlnode_get_child(packet, "vCard")) ||
1161 (vcard = xmlnode_get_child_with_namespace(packet, "query", "vcard-temp"))) 1200 (vcard = xmlnode_get_child_with_namespace(packet, "query", "vcard-temp")))
1162 { 1201 {
1163 txt = xmlnode_to_str(vcard, NULL); 1202 txt = xmlnode_to_str(vcard, NULL);
1185 jabber_iq_set_callback(iq, jabber_vcard_save_mine, NULL); 1224 jabber_iq_set_callback(iq, jabber_vcard_save_mine, NULL);
1186 1225
1187 jabber_iq_send(iq); 1226 jabber_iq_send(iq);
1188 } 1227 }
1189 1228
1190 static void jabber_vcard_parse(JabberStream *js, xmlnode *packet, gpointer data) 1229 static void jabber_vcard_parse(JabberStream *js, const char *from,
1191 { 1230 JabberIqType type, const char *id,
1192 const char *id, *from; 1231 xmlnode *packet, gpointer data)
1232 {
1193 char *bare_jid; 1233 char *bare_jid;
1194 char *text; 1234 char *text;
1195 char *serverside_alias = NULL; 1235 char *serverside_alias = NULL;
1196 xmlnode *vcard; 1236 xmlnode *vcard;
1197 PurpleBuddy *b; 1237 PurpleBuddy *b;
1198 JabberBuddyInfo *jbi = data; 1238 JabberBuddyInfo *jbi = data;
1199 PurpleNotifyUserInfo *user_info; 1239 PurpleNotifyUserInfo *user_info;
1200
1201 from = xmlnode_get_attrib(packet, "from");
1202 id = xmlnode_get_attrib(packet, "id");
1203 1240
1204 if(!jbi) 1241 if(!jbi)
1205 return; 1242 return;
1206 1243
1207 jabber_buddy_info_remove_id(jbi, id); 1244 jabber_buddy_info_remove_id(jbi, id);
1548 { 1585 {
1549 JabberBuddyInfoResource *jbri = data; 1586 JabberBuddyInfoResource *jbri = data;
1550 g_free(jbri); 1587 g_free(jbri);
1551 } 1588 }
1552 1589
1553 static void jabber_version_parse(JabberStream *js, xmlnode *packet, gpointer data) 1590 static void jabber_version_parse(JabberStream *js, const char *from,
1591 JabberIqType type, const char *id,
1592 xmlnode *packet, gpointer data)
1554 { 1593 {
1555 JabberBuddyInfo *jbi = data; 1594 JabberBuddyInfo *jbi = data;
1556 const char *type, *id, *from;
1557 xmlnode *query; 1595 xmlnode *query;
1558 char *resource_name; 1596 char *resource_name;
1559 1597
1560 g_return_if_fail(jbi != NULL); 1598 g_return_if_fail(jbi != NULL);
1561 1599
1562 type = xmlnode_get_attrib(packet, "type");
1563 id = xmlnode_get_attrib(packet, "id");
1564 from = xmlnode_get_attrib(packet, "from");
1565
1566 jabber_buddy_info_remove_id(jbi, id); 1600 jabber_buddy_info_remove_id(jbi, id);
1567 1601
1568 if(!from) 1602 if(!from)
1569 return; 1603 return;
1570 1604
1571 resource_name = jabber_get_resource(from); 1605 resource_name = jabber_get_resource(from);
1572 1606
1573 if(resource_name) { 1607 if(resource_name) {
1574 if(type && !strcmp(type, "result")) { 1608 if (type == JABBER_IQ_RESULT) {
1575 if((query = xmlnode_get_child(packet, "query"))) { 1609 if((query = xmlnode_get_child(packet, "query"))) {
1576 JabberBuddyResource *jbr = jabber_buddy_find_resource(jbi->jb, resource_name); 1610 JabberBuddyResource *jbr = jabber_buddy_find_resource(jbi->jb, resource_name);
1577 if(jbr) { 1611 if(jbr) {
1578 xmlnode *node; 1612 xmlnode *node;
1579 if((node = xmlnode_get_child(query, "name"))) { 1613 if((node = xmlnode_get_child(query, "name"))) {
1592 } 1626 }
1593 1627
1594 jabber_buddy_info_show_if_ready(jbi); 1628 jabber_buddy_info_show_if_ready(jbi);
1595 } 1629 }
1596 1630
1597 static void jabber_last_parse(JabberStream *js, xmlnode *packet, gpointer data) 1631 static void jabber_last_parse(JabberStream *js, const char *from,
1632 JabberIqType type, const char *id,
1633 xmlnode *packet, gpointer data)
1598 { 1634 {
1599 JabberBuddyInfo *jbi = data; 1635 JabberBuddyInfo *jbi = data;
1600 xmlnode *query; 1636 xmlnode *query;
1601 char *resource_name; 1637 char *resource_name;
1602 const char *type, *id, *from, *seconds; 1638 const char *seconds;
1603 1639
1604 g_return_if_fail(jbi != NULL); 1640 g_return_if_fail(jbi != NULL);
1605 1641
1606 type = xmlnode_get_attrib(packet, "type");
1607 id = xmlnode_get_attrib(packet, "id");
1608 from = xmlnode_get_attrib(packet, "from");
1609
1610 jabber_buddy_info_remove_id(jbi, id); 1642 jabber_buddy_info_remove_id(jbi, id);
1611 1643
1612 if(!from) 1644 if(!from)
1613 return; 1645 return;
1614 1646
1615 resource_name = jabber_get_resource(from); 1647 resource_name = jabber_get_resource(from);
1616 1648
1617 if(resource_name) { 1649 if(resource_name) {
1618 if(type && !strcmp(type, "result")) { 1650 if (type == JABBER_IQ_RESULT) {
1619 if((query = xmlnode_get_child(packet, "query"))) { 1651 if((query = xmlnode_get_child(packet, "query"))) {
1620 seconds = xmlnode_get_attrib(query, "seconds"); 1652 seconds = xmlnode_get_attrib(query, "seconds");
1621 if(seconds) { 1653 if(seconds) {
1622 char *end = NULL; 1654 char *end = NULL;
1623 long sec = strtol(seconds, &end, 10); 1655 long sec = strtol(seconds, &end, 10);
1634 } 1666 }
1635 1667
1636 jabber_buddy_info_show_if_ready(jbi); 1668 jabber_buddy_info_show_if_ready(jbi);
1637 } 1669 }
1638 1670
1671 static void jabber_time_parse(JabberStream *js, const char *from,
1672 JabberIqType type, const char *id,
1673 xmlnode *packet, gpointer data)
1674 {
1675 JabberBuddyInfo *jbi = data;
1676 JabberBuddyResource *jbr;
1677 char *resource_name;
1678
1679 g_return_if_fail(jbi != NULL);
1680
1681 jabber_buddy_info_remove_id(jbi, id);
1682
1683 if (!from)
1684 return;
1685
1686 resource_name = jabber_get_resource(from);
1687 jbr = resource_name ? jabber_buddy_find_resource(jbi->jb, resource_name) : NULL;
1688 g_free(resource_name);
1689 if (jbr) {
1690 if (type == JABBER_IQ_RESULT) {
1691 xmlnode *time = xmlnode_get_child(packet, "time");
1692 xmlnode *tzo = time ? xmlnode_get_child(time, "tzo") : NULL;
1693 char *tzo_data = tzo ? xmlnode_get_data(tzo) : NULL;
1694 if (tzo_data) {
1695 char *c = tzo_data;
1696 int hours, minutes;
1697 if (tzo_data[0] == 'Z' && tzo_data[1] == '\0') {
1698 jbr->tz_off = 0;
1699 } else {
1700 gboolean offset_positive = (tzo_data[0] == '+');
1701 /* [+-]HH:MM */
1702 if (((*c == '+' || *c == '-') && (c = c + 1)) &&
1703 sscanf(c, "%02d:%02d", &hours, &minutes) == 2) {
1704 jbr->tz_off = 60*60*hours + 60*minutes;
1705 if (!offset_positive)
1706 jbr->tz_off *= -1;
1707 } else {
1708 purple_debug_info("jabber", "Ignoring malformed timezone %s",
1709 tzo_data);
1710 }
1711 }
1712
1713 g_free(tzo_data);
1714 }
1715 }
1716 }
1717
1718 jabber_buddy_info_show_if_ready(jbi);
1719 }
1720
1639 void jabber_buddy_remove_all_pending_buddy_info_requests(JabberStream *js) 1721 void jabber_buddy_remove_all_pending_buddy_info_requests(JabberStream *js)
1640 { 1722 {
1641 if (js->pending_buddy_info_requests) 1723 if (js->pending_buddy_info_requests)
1642 { 1724 {
1643 JabberBuddyInfo *jbi; 1725 JabberBuddyInfo *jbi;
1761 * office. */ 1843 * office. */
1762 if(!_client_is_blacklisted(jbr, "jabber:iq:last")) { 1844 if(!_client_is_blacklisted(jbr, "jabber:iq:last")) {
1763 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:last"); 1845 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:last");
1764 xmlnode_set_attrib(iq->node, "to", full_jid); 1846 xmlnode_set_attrib(iq->node, "to", full_jid);
1765 jabber_iq_set_callback(iq, jabber_last_parse, jbi); 1847 jabber_iq_set_callback(iq, jabber_last_parse, jbi);
1848 jbi->ids = g_slist_prepend(jbi->ids, g_strdup(iq->id));
1849 jabber_iq_send(iq);
1850 }
1851
1852 if (jbr->tz_off == PURPLE_NO_TZ_OFF &&
1853 (!jbr->caps ||
1854 jabber_resource_has_capability(jbr, "urn:xmpp:time"))) {
1855 xmlnode *child;
1856 iq = jabber_iq_new(js, JABBER_IQ_GET);
1857 xmlnode_set_attrib(iq->node, "to", full_jid);
1858 child = xmlnode_new_child(iq->node, "time");
1859 xmlnode_set_namespace(child, "urn:xmpp:time");
1860 jabber_iq_set_callback(iq, jabber_time_parse, jbi);
1766 jbi->ids = g_slist_prepend(jbi->ids, g_strdup(iq->id)); 1861 jbi->ids = g_slist_prepend(jbi->ids, g_strdup(iq->id));
1767 jabber_iq_send(iq); 1862 jabber_iq_send(iq);
1768 } 1863 }
1769 1864
1770 g_free(full_jid); 1865 g_free(full_jid);
2161 /* XXX find out the jid */ 2256 /* XXX find out the jid */
2162 purple_blist_request_add_buddy(purple_connection_get_account(gc), 2257 purple_blist_request_add_buddy(purple_connection_get_account(gc),
2163 g_list_nth_data(row, 0), NULL, NULL); 2258 g_list_nth_data(row, 0), NULL, NULL);
2164 } 2259 }
2165 2260
2166 static void user_search_result_cb(JabberStream *js, xmlnode *packet, gpointer data) 2261 static void user_search_result_cb(JabberStream *js, const char *from,
2262 JabberIqType type, const char *id,
2263 xmlnode *packet, gpointer data)
2167 { 2264 {
2168 PurpleNotifySearchResults *results; 2265 PurpleNotifySearchResults *results;
2169 PurpleNotifySearchColumn *column; 2266 PurpleNotifySearchColumn *column;
2170 xmlnode *x, *query, *item, *field; 2267 xmlnode *x, *query, *item, *field;
2171 2268
2357 "Note: Each field supports wild card searches (%)"), 2454 "Note: Each field supports wild card searches (%)"),
2358 NULL 2455 NULL
2359 }; 2456 };
2360 #endif 2457 #endif
2361 2458
2362 static void user_search_fields_result_cb(JabberStream *js, xmlnode *packet, gpointer data) 2459 static void user_search_fields_result_cb(JabberStream *js, const char *from,
2460 JabberIqType type, const char *id,
2461 xmlnode *packet, gpointer data)
2363 { 2462 {
2364 xmlnode *query, *x; 2463 xmlnode *query, *x;
2365 const char *from, *type; 2464
2366 2465 if (!from)
2367 if(!(from = xmlnode_get_attrib(packet, "from"))) 2466 return;
2368 return; 2467
2369 2468 if (type == JABBER_IQ_ERROR) {
2370 if(!(type = xmlnode_get_attrib(packet, "type")) || !strcmp(type, "error")) {
2371 char *msg = jabber_parse_error(js, packet, NULL); 2469 char *msg = jabber_parse_error(js, packet, NULL);
2372 2470
2373 if(!msg) 2471 if(!msg)
2374 msg = g_strdup(_("Unknown error")); 2472 msg = g_strdup(_("Unknown error"));
2375 2473