comparison libpurple/protocols/jabber/buddy.c @ 26504:7fba18b43da3

propagate from branch 'im.pidgin.pidgin' (head eed0598058a6e7cc5da7ad99f06bfe136291d2f9) to branch 'im.pidgin.cpw.malu.xmpp.idle' (head 6e86275961530024d108fa7f061327fd01a92969)
author Marcus Lundblad <ml@update.uu.se>
date Tue, 07 Apr 2009 05:10:52 +0000
parents 6b0409164425 00870e5f2e90
children 925a5a7605b6
comparison
equal deleted inserted replaced
26430:12089d993a0c 26504:7fba18b43da3
158 if(!jbr) { 158 if(!jbr) {
159 jbr = g_new0(JabberBuddyResource, 1); 159 jbr = g_new0(JabberBuddyResource, 1);
160 jbr->jb = jb; 160 jbr->jb = jb;
161 jbr->name = g_strdup(resource); 161 jbr->name = g_strdup(resource);
162 jbr->capabilities = JABBER_CAP_XHTML; 162 jbr->capabilities = JABBER_CAP_XHTML;
163 jbr->tz_off = PURPLE_NO_TZ_OFF;
163 jb->resources = g_list_append(jb->resources, jbr); 164 jb->resources = g_list_append(jb->resources, jbr);
164 } 165 }
165 jbr->priority = priority; 166 jbr->priority = priority;
166 jbr->state = state; 167 jbr->state = state;
167 g_free(jbr->status); 168 g_free(jbr->status);
799 g_free(tmp); 800 g_free(tmp);
800 801
801 if(jbr->client.os) { 802 if(jbr->client.os) {
802 purple_notify_user_info_prepend_pair(user_info, _("Operating System"), jbr->client.os); 803 purple_notify_user_info_prepend_pair(user_info, _("Operating System"), jbr->client.os);
803 } 804 }
805 }
806 if (jbr && jbr->tz_off != PURPLE_NO_TZ_OFF) {
807 time_t now_t;
808 struct tm *now;
809 char *timestamp;
810 time(&now_t);
811 now_t += jbr->tz_off;
812 now = gmtime(&now_t);
813
814 timestamp = g_strdup_printf("%s %c%02d%02d", purple_time_format(now),
815 jbr->tz_off < 0 ? '-' : '+',
816 abs(jbr->tz_off / (60*60)),
817 abs((jbr->tz_off % (60*60)) / 60));
818 purple_notify_user_info_prepend_pair(user_info, _("Local Time"), timestamp);
819 g_free(timestamp);
804 } 820 }
805 if(jbir) { 821 if(jbir) {
806 if(jbir->idle_seconds > 0) { 822 if(jbir->idle_seconds > 0) {
807 char *idle = purple_str_seconds_to_string(jbir->idle_seconds); 823 char *idle = purple_str_seconds_to_string(jbir->idle_seconds);
808 purple_notify_user_info_prepend_pair(user_info, _("Idle"), idle); 824 purple_notify_user_info_prepend_pair(user_info, _("Idle"), idle);
918 feature = _("User Browsing"); 934 feature = _("User Browsing");
919 else if(!strcmp(feature, "http://jabber.org/protocol/gaming")) 935 else if(!strcmp(feature, "http://jabber.org/protocol/gaming"))
920 feature = _("User Gaming"); 936 feature = _("User Gaming");
921 else if(!strcmp(feature, "http://jabber.org/protocol/viewing")) 937 else if(!strcmp(feature, "http://jabber.org/protocol/viewing"))
922 feature = _("User Viewing"); 938 feature = _("User Viewing");
923 else if(!strcmp(feature, "urn:xmpp:ping") || !strcmp(feature, "http://www.xmpp.org/extensions/xep-0199.html#ns")) 939 else if(!strcmp(feature, "urn:xmpp:ping"))
924 feature = _("Ping"); 940 feature = _("Ping");
925 else if(!strcmp(feature, "http://www.xmpp.org/extensions/xep-0200.html#ns")) 941 else if(!strcmp(feature, "http://www.xmpp.org/extensions/xep-0200.html#ns"))
926 feature = _("Stanza Encryption"); 942 feature = _("Stanza Encryption");
927 else if(!strcmp(feature, "urn:xmpp:time")) 943 else if(!strcmp(feature, "urn:xmpp:time"))
928 feature = _("Entity Time"); 944 feature = _("Entity Time");
968 g_free(tmp); 984 g_free(tmp);
969 985
970 if(jbr->client.os) { 986 if(jbr->client.os) {
971 purple_notify_user_info_prepend_pair(user_info, _("Operating System"), jbr->client.os); 987 purple_notify_user_info_prepend_pair(user_info, _("Operating System"), jbr->client.os);
972 } 988 }
989 }
990
991 if (jbr->tz_off != PURPLE_NO_TZ_OFF) {
992 time_t now_t;
993 struct tm *now;
994 char *timestamp;
995 time(&now_t);
996 now_t += jbr->tz_off;
997 now = gmtime(&now_t);
998
999 timestamp = g_strdup_printf("%s %c%02d%02d", purple_time_format(now),
1000 jbr->tz_off < 0 ? '-' : '+',
1001 abs(jbr->tz_off / (60*60)),
1002 abs((jbr->tz_off % (60*60)) / 60));
1003 purple_notify_user_info_prepend_pair(user_info, _("Local Time"), timestamp);
1004 g_free(timestamp);
973 } 1005 }
974 1006
975 if(jbr->name && (jbir = g_hash_table_lookup(jbi->resources, jbr->name))) { 1007 if(jbr->name && (jbir = g_hash_table_lookup(jbi->resources, jbr->name))) {
976 if(jbir->idle_seconds > 0) { 1008 if(jbir->idle_seconds > 0) {
977 char *idle = purple_str_seconds_to_string(jbir->idle_seconds); 1009 char *idle = purple_str_seconds_to_string(jbir->idle_seconds);
1088 feature = _("User Browsing"); 1120 feature = _("User Browsing");
1089 else if(!strcmp(feature, "http://jabber.org/protocol/gaming")) 1121 else if(!strcmp(feature, "http://jabber.org/protocol/gaming"))
1090 feature = _("User Gaming"); 1122 feature = _("User Gaming");
1091 else if(!strcmp(feature, "http://jabber.org/protocol/viewing")) 1123 else if(!strcmp(feature, "http://jabber.org/protocol/viewing"))
1092 feature = _("User Viewing"); 1124 feature = _("User Viewing");
1093 else if(!strcmp(feature, "urn:xmpp:ping") || !strcmp(feature, "http://www.xmpp.org/extensions/xep-0199.html#ns")) 1125 else if(!strcmp(feature, "urn:xmpp:ping"))
1094 feature = _("Ping"); 1126 feature = _("Ping");
1095 else if(!strcmp(feature, "http://www.xmpp.org/extensions/xep-0200.html#ns")) 1127 else if(!strcmp(feature, "http://www.xmpp.org/extensions/xep-0200.html#ns"))
1096 feature = _("Stanza Encryption"); 1128 feature = _("Stanza Encryption");
1097 else if(!strcmp(feature, "urn:xmpp:time")) 1129 else if(!strcmp(feature, "urn:xmpp:time"))
1098 feature = _("Entity Time"); 1130 feature = _("Entity Time");
1154 } 1186 }
1155 l = l->next; 1187 l = l->next;
1156 } 1188 }
1157 } 1189 }
1158 1190
1159 static void jabber_vcard_save_mine(JabberStream *js, xmlnode *packet, gpointer data) 1191 static void jabber_vcard_save_mine(JabberStream *js, const char *from,
1192 JabberIqType type, const char *id,
1193 xmlnode *packet, gpointer data)
1160 { 1194 {
1161 xmlnode *vcard; 1195 xmlnode *vcard;
1162 char *txt; 1196 char *txt;
1163 PurpleStoredImage *img; 1197 PurpleStoredImage *img;
1198
1199 if (type == JABBER_IQ_ERROR) {
1200 purple_debug_warning("jabber", "Server returned error while retrieving vCard");
1201 return;
1202 }
1164 1203
1165 if((vcard = xmlnode_get_child(packet, "vCard")) || 1204 if((vcard = xmlnode_get_child(packet, "vCard")) ||
1166 (vcard = xmlnode_get_child_with_namespace(packet, "query", "vcard-temp"))) 1205 (vcard = xmlnode_get_child_with_namespace(packet, "query", "vcard-temp")))
1167 { 1206 {
1168 txt = xmlnode_to_str(vcard, NULL); 1207 txt = xmlnode_to_str(vcard, NULL);
1190 jabber_iq_set_callback(iq, jabber_vcard_save_mine, NULL); 1229 jabber_iq_set_callback(iq, jabber_vcard_save_mine, NULL);
1191 1230
1192 jabber_iq_send(iq); 1231 jabber_iq_send(iq);
1193 } 1232 }
1194 1233
1195 static void jabber_vcard_parse(JabberStream *js, xmlnode *packet, gpointer data) 1234 static void jabber_vcard_parse(JabberStream *js, const char *from,
1196 { 1235 JabberIqType type, const char *id,
1197 const char *id, *from; 1236 xmlnode *packet, gpointer data)
1237 {
1198 char *bare_jid; 1238 char *bare_jid;
1199 char *text; 1239 char *text;
1200 char *serverside_alias = NULL; 1240 char *serverside_alias = NULL;
1201 xmlnode *vcard; 1241 xmlnode *vcard;
1202 PurpleBuddy *b; 1242 PurpleBuddy *b;
1203 JabberBuddyInfo *jbi = data; 1243 JabberBuddyInfo *jbi = data;
1204 PurpleNotifyUserInfo *user_info; 1244 PurpleNotifyUserInfo *user_info;
1205
1206 from = xmlnode_get_attrib(packet, "from");
1207 id = xmlnode_get_attrib(packet, "id");
1208 1245
1209 if(!jbi) 1246 if(!jbi)
1210 return; 1247 return;
1211 1248
1212 jabber_buddy_info_remove_id(jbi, id); 1249 jabber_buddy_info_remove_id(jbi, id);
1553 { 1590 {
1554 JabberBuddyInfoResource *jbri = data; 1591 JabberBuddyInfoResource *jbri = data;
1555 g_free(jbri); 1592 g_free(jbri);
1556 } 1593 }
1557 1594
1558 static void jabber_version_parse(JabberStream *js, xmlnode *packet, gpointer data) 1595 static void jabber_version_parse(JabberStream *js, const char *from,
1596 JabberIqType type, const char *id,
1597 xmlnode *packet, gpointer data)
1559 { 1598 {
1560 JabberBuddyInfo *jbi = data; 1599 JabberBuddyInfo *jbi = data;
1561 const char *type, *id, *from;
1562 xmlnode *query; 1600 xmlnode *query;
1563 char *resource_name; 1601 char *resource_name;
1564 1602
1565 g_return_if_fail(jbi != NULL); 1603 g_return_if_fail(jbi != NULL);
1566 1604
1567 type = xmlnode_get_attrib(packet, "type");
1568 id = xmlnode_get_attrib(packet, "id");
1569 from = xmlnode_get_attrib(packet, "from");
1570
1571 jabber_buddy_info_remove_id(jbi, id); 1605 jabber_buddy_info_remove_id(jbi, id);
1572 1606
1573 if(!from) 1607 if(!from)
1574 return; 1608 return;
1575 1609
1576 resource_name = jabber_get_resource(from); 1610 resource_name = jabber_get_resource(from);
1577 1611
1578 if(resource_name) { 1612 if(resource_name) {
1579 if(type && !strcmp(type, "result")) { 1613 if (type == JABBER_IQ_RESULT) {
1580 if((query = xmlnode_get_child(packet, "query"))) { 1614 if((query = xmlnode_get_child(packet, "query"))) {
1581 JabberBuddyResource *jbr = jabber_buddy_find_resource(jbi->jb, resource_name); 1615 JabberBuddyResource *jbr = jabber_buddy_find_resource(jbi->jb, resource_name);
1582 if(jbr) { 1616 if(jbr) {
1583 xmlnode *node; 1617 xmlnode *node;
1584 if((node = xmlnode_get_child(query, "name"))) { 1618 if((node = xmlnode_get_child(query, "name"))) {
1597 } 1631 }
1598 1632
1599 jabber_buddy_info_show_if_ready(jbi); 1633 jabber_buddy_info_show_if_ready(jbi);
1600 } 1634 }
1601 1635
1602 static void jabber_last_parse(JabberStream *js, xmlnode *packet, gpointer data) 1636 static void jabber_last_parse(JabberStream *js, const char *from,
1637 JabberIqType type, const char *id,
1638 xmlnode *packet, gpointer data)
1603 { 1639 {
1604 JabberBuddyInfo *jbi = data; 1640 JabberBuddyInfo *jbi = data;
1605 xmlnode *query; 1641 xmlnode *query;
1606 char *resource_name; 1642 char *resource_name;
1607 const char *type, *id, *from, *seconds; 1643 const char *seconds;
1608 1644
1609 g_return_if_fail(jbi != NULL); 1645 g_return_if_fail(jbi != NULL);
1610 1646
1611 type = xmlnode_get_attrib(packet, "type");
1612 id = xmlnode_get_attrib(packet, "id");
1613 from = xmlnode_get_attrib(packet, "from");
1614
1615 jabber_buddy_info_remove_id(jbi, id); 1647 jabber_buddy_info_remove_id(jbi, id);
1616 1648
1617 if(!from) 1649 if(!from)
1618 return; 1650 return;
1619 1651
1620 resource_name = jabber_get_resource(from); 1652 resource_name = jabber_get_resource(from);
1621 1653
1622 if(resource_name) { 1654 if(resource_name) {
1623 if(type && !strcmp(type, "result")) { 1655 if (type == JABBER_IQ_RESULT) {
1624 if((query = xmlnode_get_child(packet, "query"))) { 1656 if((query = xmlnode_get_child(packet, "query"))) {
1625 seconds = xmlnode_get_attrib(query, "seconds"); 1657 seconds = xmlnode_get_attrib(query, "seconds");
1626 if(seconds) { 1658 if(seconds) {
1627 char *end = NULL; 1659 char *end = NULL;
1628 long sec = strtol(seconds, &end, 10); 1660 long sec = strtol(seconds, &end, 10);
1676 } 1708 }
1677 1709
1678 jabber_buddy_info_show_if_ready(jbi); 1710 jabber_buddy_info_show_if_ready(jbi);
1679 } 1711 }
1680 1712
1713 static void jabber_time_parse(JabberStream *js, const char *from,
1714 JabberIqType type, const char *id,
1715 xmlnode *packet, gpointer data)
1716 {
1717 JabberBuddyInfo *jbi = data;
1718 JabberBuddyResource *jbr;
1719 char *resource_name;
1720
1721 g_return_if_fail(jbi != NULL);
1722
1723 jabber_buddy_info_remove_id(jbi, id);
1724
1725 if (!from)
1726 return;
1727
1728 resource_name = jabber_get_resource(from);
1729 jbr = resource_name ? jabber_buddy_find_resource(jbi->jb, resource_name) : NULL;
1730 g_free(resource_name);
1731 if (jbr) {
1732 if (type == JABBER_IQ_RESULT) {
1733 xmlnode *time = xmlnode_get_child(packet, "time");
1734 xmlnode *tzo = time ? xmlnode_get_child(time, "tzo") : NULL;
1735 char *tzo_data = tzo ? xmlnode_get_data(tzo) : NULL;
1736 if (tzo_data) {
1737 char *c = tzo_data;
1738 int hours, minutes;
1739 if (tzo_data[0] == 'Z' && tzo_data[1] == '\0') {
1740 jbr->tz_off = 0;
1741 } else {
1742 gboolean offset_positive = (tzo_data[0] == '+');
1743 /* [+-]HH:MM */
1744 if (((*c == '+' || *c == '-') && (c = c + 1)) &&
1745 sscanf(c, "%02d:%02d", &hours, &minutes) == 2) {
1746 jbr->tz_off = 60*60*hours + 60*minutes;
1747 if (!offset_positive)
1748 jbr->tz_off *= -1;
1749 } else {
1750 purple_debug_info("jabber", "Ignoring malformed timezone %s",
1751 tzo_data);
1752 }
1753 }
1754
1755 g_free(tzo_data);
1756 }
1757 }
1758 }
1759
1760 jabber_buddy_info_show_if_ready(jbi);
1761 }
1762
1681 void jabber_buddy_remove_all_pending_buddy_info_requests(JabberStream *js) 1763 void jabber_buddy_remove_all_pending_buddy_info_requests(JabberStream *js)
1682 { 1764 {
1683 if (js->pending_buddy_info_requests) 1765 if (js->pending_buddy_info_requests)
1684 { 1766 {
1685 JabberBuddyInfo *jbi; 1767 JabberBuddyInfo *jbi;
1803 * office. */ 1885 * office. */
1804 if(!_client_is_blacklisted(jbr, "jabber:iq:last")) { 1886 if(!_client_is_blacklisted(jbr, "jabber:iq:last")) {
1805 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:last"); 1887 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:last");
1806 xmlnode_set_attrib(iq->node, "to", full_jid); 1888 xmlnode_set_attrib(iq->node, "to", full_jid);
1807 jabber_iq_set_callback(iq, jabber_last_parse, jbi); 1889 jabber_iq_set_callback(iq, jabber_last_parse, jbi);
1890 jbi->ids = g_slist_prepend(jbi->ids, g_strdup(iq->id));
1891 jabber_iq_send(iq);
1892 }
1893
1894 if (jbr->tz_off == PURPLE_NO_TZ_OFF &&
1895 (!jbr->caps ||
1896 jabber_resource_has_capability(jbr, "urn:xmpp:time"))) {
1897 xmlnode *child;
1898 iq = jabber_iq_new(js, JABBER_IQ_GET);
1899 xmlnode_set_attrib(iq->node, "to", full_jid);
1900 child = xmlnode_new_child(iq->node, "time");
1901 xmlnode_set_namespace(child, "urn:xmpp:time");
1902 jabber_iq_set_callback(iq, jabber_time_parse, jbi);
1808 jbi->ids = g_slist_prepend(jbi->ids, g_strdup(iq->id)); 1903 jbi->ids = g_slist_prepend(jbi->ids, g_strdup(iq->id));
1809 jabber_iq_send(iq); 1904 jabber_iq_send(iq);
1810 } 1905 }
1811 1906
1812 g_free(full_jid); 1907 g_free(full_jid);
2203 /* XXX find out the jid */ 2298 /* XXX find out the jid */
2204 purple_blist_request_add_buddy(purple_connection_get_account(gc), 2299 purple_blist_request_add_buddy(purple_connection_get_account(gc),
2205 g_list_nth_data(row, 0), NULL, NULL); 2300 g_list_nth_data(row, 0), NULL, NULL);
2206 } 2301 }
2207 2302
2208 static void user_search_result_cb(JabberStream *js, xmlnode *packet, gpointer data) 2303 static void user_search_result_cb(JabberStream *js, const char *from,
2304 JabberIqType type, const char *id,
2305 xmlnode *packet, gpointer data)
2209 { 2306 {
2210 PurpleNotifySearchResults *results; 2307 PurpleNotifySearchResults *results;
2211 PurpleNotifySearchColumn *column; 2308 PurpleNotifySearchColumn *column;
2212 xmlnode *x, *query, *item, *field; 2309 xmlnode *x, *query, *item, *field;
2213 2310
2399 "Note: Each field supports wild card searches (%)"), 2496 "Note: Each field supports wild card searches (%)"),
2400 NULL 2497 NULL
2401 }; 2498 };
2402 #endif 2499 #endif
2403 2500
2404 static void user_search_fields_result_cb(JabberStream *js, xmlnode *packet, gpointer data) 2501 static void user_search_fields_result_cb(JabberStream *js, const char *from,
2502 JabberIqType type, const char *id,
2503 xmlnode *packet, gpointer data)
2405 { 2504 {
2406 xmlnode *query, *x; 2505 xmlnode *query, *x;
2407 const char *from, *type; 2506
2408 2507 if (!from)
2409 if(!(from = xmlnode_get_attrib(packet, "from"))) 2508 return;
2410 return; 2509
2411 2510 if (type == JABBER_IQ_ERROR) {
2412 if(!(type = xmlnode_get_attrib(packet, "type")) || !strcmp(type, "error")) {
2413 char *msg = jabber_parse_error(js, packet, NULL); 2511 char *msg = jabber_parse_error(js, packet, NULL);
2414 2512
2415 if(!msg) 2513 if(!msg)
2416 msg = g_strdup(_("Unknown error")); 2514 msg = g_strdup(_("Unknown error"));
2417 2515