Mercurial > ~mikael > mcabber > hg
comparison mcabber/src/xmpp.c @ 1600:c5ee395fbc8c
Updated Entity Capabilities support (XEP-0115)
author | franky |
---|---|
date | Tue, 23 Sep 2008 10:59:25 +0200 |
parents | dcd5d4c75199 |
children | f4a2c6f767d1 |
comparison
equal
deleted
inserted
replaced
1599:dcd5d4c75199 | 1600:c5ee395fbc8c |
---|---|
23 */ | 23 */ |
24 #include <stdlib.h> | 24 #include <stdlib.h> |
25 #include <string.h> | 25 #include <string.h> |
26 #include <sys/utsname.h> | 26 #include <sys/utsname.h> |
27 | 27 |
28 #include "caps.h" | |
28 #include "commands.h" | 29 #include "commands.h" |
29 #include "events.h" | 30 #include "events.h" |
30 #include "histolog.h" | 31 #include "histolog.h" |
31 #include "hooks.h" | 32 #include "hooks.h" |
32 #include "logprint.h" | 33 #include "logprint.h" |
1251 } | 1252 } |
1252 | 1253 |
1253 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | 1254 return LM_HANDLER_RESULT_REMOVE_MESSAGE; |
1254 } | 1255 } |
1255 | 1256 |
1257 static LmHandlerResult cb_caps(LmMessageHandler *h, LmConnection *c, | |
1258 LmMessage *m, gpointer user_data) | |
1259 { | |
1260 char *ver = user_data; | |
1261 | |
1262 if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_ERROR) { | |
1263 display_server_error(lm_message_node_get_child(m->node, "error")); | |
1264 } else if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_RESULT) { | |
1265 LmMessageNode *info; | |
1266 LmMessageNode *query = lm_message_node_get_child(m->node, "query"); | |
1267 | |
1268 caps_add(ver); | |
1269 info = lm_message_node_get_child(query, "identity"); | |
1270 if (info) | |
1271 caps_set_identity(ver, lm_message_node_get_attribute(info, "category"), | |
1272 lm_message_node_get_attribute(info, "name"), | |
1273 lm_message_node_get_attribute(info, "type")); | |
1274 info = lm_message_node_get_child(query, "feature"); | |
1275 while (info) { | |
1276 if (!g_strcmp0(info->name, "feature")) | |
1277 caps_add_feature(ver, lm_message_node_get_attribute(info, "var")); | |
1278 info = info->next; | |
1279 } | |
1280 } | |
1281 g_free(ver); | |
1282 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | |
1283 } | |
1284 | |
1256 static LmHandlerResult handle_presence(LmMessageHandler *handler, | 1285 static LmHandlerResult handle_presence(LmMessageHandler *handler, |
1257 LmConnection *connection, | 1286 LmConnection *connection, |
1258 LmMessage *m, gpointer user_data) | 1287 LmMessage *m, gpointer user_data) |
1259 { | 1288 { |
1260 char *r; | 1289 char *r; |
1261 const char *from, *rname, *p=NULL, *ustmsg=NULL; | 1290 const char *from, *rname, *p=NULL, *ustmsg=NULL; |
1262 enum imstatus ust; | 1291 enum imstatus ust; |
1263 char bpprio; | 1292 char bpprio; |
1264 time_t timestamp = 0L; | 1293 time_t timestamp = 0L; |
1265 LmMessageNode *muc_packet; | 1294 LmMessageNode *muc_packet, *caps; |
1266 | 1295 |
1267 //Check for MUC presence packet | 1296 //Check for MUC presence packet |
1268 muc_packet = lm_message_node_find_xmlns | 1297 muc_packet = lm_message_node_find_xmlns |
1269 (m->node, "http://jabber.org/protocol/muc#user"); | 1298 (m->node, "http://jabber.org/protocol/muc#user"); |
1270 | 1299 |
1341 // Presence signature processing | 1370 // Presence signature processing |
1342 if (!ustmsg) | 1371 if (!ustmsg) |
1343 ustmsg = ""; // Some clients omit the <status/> element :-( | 1372 ustmsg = ""; // Some clients omit the <status/> element :-( |
1344 check_signature(r, rname, lm_message_node_find_xmlns(m->node, NS_SIGNED), | 1373 check_signature(r, rname, lm_message_node_find_xmlns(m->node, NS_SIGNED), |
1345 ustmsg); | 1374 ustmsg); |
1375 } | |
1376 | |
1377 //XEP-0115 Entity Capabilities | |
1378 caps = lm_message_node_find_xmlns(m->node, NS_CAPS); | |
1379 if (caps) { | |
1380 const char *ver = lm_message_node_get_attribute(caps, "ver"); | |
1381 GSList *sl_buddy = NULL; | |
1382 if (rname) | |
1383 sl_buddy = roster_find(r, jidsearch, ROSTER_TYPE_USER); | |
1384 //only cache the caps if the user is on the roster | |
1385 if (sl_buddy && buddy_getonserverflag(sl_buddy->data)) { | |
1386 buddy_resource_setcaps(sl_buddy->data, rname, ver); | |
1387 | |
1388 if (!caps_has_hash(ver)) { | |
1389 char *node; | |
1390 LmMessageHandler *handler; | |
1391 LmMessage *iq = lm_message_new_with_sub_type(from, LM_MESSAGE_TYPE_IQ, | |
1392 LM_MESSAGE_SUB_TYPE_GET); | |
1393 node = g_strdup_printf("%s#%s", | |
1394 lm_message_node_get_attribute(caps, "node"), | |
1395 ver); | |
1396 lm_message_node_set_attributes | |
1397 (lm_message_node_add_child(iq->node, "query", NULL), | |
1398 "xmlns", NS_DISCO_INFO, | |
1399 "node", node, | |
1400 NULL); | |
1401 g_free(node); | |
1402 handler = lm_message_handler_new(cb_caps, g_strdup(ver), NULL); | |
1403 lm_connection_send_with_reply(connection, iq, handler, NULL); | |
1404 lm_message_unref(iq); | |
1405 lm_message_handler_unref(handler); | |
1406 } | |
1407 } | |
1346 } | 1408 } |
1347 | 1409 |
1348 g_free(r); | 1410 g_free(r); |
1349 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | 1411 return LM_HANDLER_RESULT_REMOVE_MESSAGE; |
1350 } | 1412 } |
1691 } | 1753 } |
1692 } | 1754 } |
1693 | 1755 |
1694 // insert_entity_capabilities(presence_stanza) | 1756 // insert_entity_capabilities(presence_stanza) |
1695 // Entity Capabilities (XEP-0115) | 1757 // Entity Capabilities (XEP-0115) |
1696 static void insert_entity_capabilities(LmMessageNode * x) | 1758 static void insert_entity_capabilities(LmMessageNode *x, enum imstatus status) |
1697 { | 1759 { |
1698 LmMessageNode *y; | 1760 LmMessageNode *y; |
1699 const char *ver = entity_version(); | 1761 const char *ver = entity_version(status); |
1700 char *exts, *exts2; | |
1701 | |
1702 exts = NULL; | |
1703 | 1762 |
1704 y = lm_message_node_add_child(x, "c", NULL); | 1763 y = lm_message_node_add_child(x, "c", NULL); |
1705 lm_message_node_set_attribute(y, "xmlns", NS_CAPS); | 1764 lm_message_node_set_attribute(y, "xmlns", NS_CAPS); |
1765 lm_message_node_set_attribute(y, "hash", "sha-1"); | |
1706 lm_message_node_set_attribute(y, "node", MCABBER_CAPS_NODE); | 1766 lm_message_node_set_attribute(y, "node", MCABBER_CAPS_NODE); |
1707 lm_message_node_set_attribute(y, "ver", ver); | 1767 lm_message_node_set_attribute(y, "ver", ver); |
1708 #ifdef JEP0085 | |
1709 if (!chatstates_disabled) { | |
1710 exts2 = g_strjoin(" ", "csn", exts, NULL); | |
1711 g_free(exts); | |
1712 exts = exts2; | |
1713 } | |
1714 #endif | |
1715 if (!settings_opt_get_int("iq_last_disable")) { | |
1716 exts2 = g_strjoin(" ", "iql", exts, NULL); | |
1717 g_free(exts); | |
1718 exts = exts2; | |
1719 } | |
1720 if (exts) { | |
1721 lm_message_node_set_attribute(y, "ext", exts); | |
1722 g_free(exts); | |
1723 } | |
1724 } | 1768 } |
1725 | 1769 |
1726 void xmpp_disconnect(void) | 1770 void xmpp_disconnect(void) |
1727 { | 1771 { |
1728 if (!lconnection || !lm_connection_is_authenticated(lconnection)) | 1772 if (!lconnection || !lm_connection_is_authenticated(lconnection)) |
1763 // (But we want to update internal status even when disconnected, | 1807 // (But we want to update internal status even when disconnected, |
1764 // in order to avoid some problems during network failures) | 1808 // in order to avoid some problems during network failures) |
1765 if (lm_connection_is_authenticated(lconnection)) { | 1809 if (lm_connection_is_authenticated(lconnection)) { |
1766 const char *s_msg = (st != invisible ? msg : NULL); | 1810 const char *s_msg = (st != invisible ? msg : NULL); |
1767 m = lm_message_new_presence(st, recipient, s_msg); | 1811 m = lm_message_new_presence(st, recipient, s_msg); |
1768 insert_entity_capabilities(m->node); // Entity Capabilities (XEP-0115) | 1812 insert_entity_capabilities(m->node, st); // Entity Capabilities (XEP-0115) |
1769 #ifdef HAVE_GPGME | 1813 #ifdef HAVE_GPGME |
1770 if (!do_not_sign && gpg_enabled()) { | 1814 if (!do_not_sign && gpg_enabled()) { |
1771 char *signature; | 1815 char *signature; |
1772 signature = gpg_sign(s_msg ? s_msg : ""); | 1816 signature = gpg_sign(s_msg ? s_msg : ""); |
1773 if (signature) { | 1817 if (signature) { |