comparison mcabber/mcabber/xmpp.c @ 1731:4fbfae993c24

Improve login process The roster and private storage elements are requested before broadcasting our presence, because we want the roster before we receive our contacts presence notifications. This is more efficients, and also solves an issue with entity capabilities (as we do not store caps for unknown items).
author Mikael Berthe <mikael@lilotux.net>
date Sun, 28 Feb 2010 18:50:30 +0100
parents 860b58a0e8da
children a9b0364c0cb2
comparison
equal deleted inserted replaced
1730:860b58a0e8da 1731:4fbfae993c24
849 849
850 static void connection_auth_cb(LmConnection *connection, gboolean success, 850 static void connection_auth_cb(LmConnection *connection, gboolean success,
851 gpointer user_data) 851 gpointer user_data)
852 { 852 {
853 if (success) { 853 if (success) {
854
855 xmpp_iq_request(NULL, NS_ROSTER);
856 xmpp_request_storage("storage:bookmarks");
857 xmpp_request_storage("storage:rosternotes");
858
859 /* XXX Not needed before xmpp_setprevstatus()
854 LmMessage *m; 860 LmMessage *m;
855
856 m = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_PRESENCE, 861 m = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_PRESENCE,
857 LM_MESSAGE_SUB_TYPE_AVAILABLE); 862 LM_MESSAGE_SUB_TYPE_AVAILABLE);
858 lm_connection_send(connection, m, NULL); 863 lm_connection_send(connection, m, NULL);
859
860 lm_message_unref(m); 864 lm_message_unref(m);
865 */
866
861 xmpp_setprevstatus(); 867 xmpp_setprevstatus();
862 xmpp_iq_request(NULL, NS_ROSTER);
863 xmpp_request_storage("storage:bookmarks");
864 xmpp_request_storage("storage:rosternotes");
865 868
866 AutoConnection = TRUE; 869 AutoConnection = TRUE;
867 } else 870 } else
868 scr_LogPrint(LPRINT_LOGNORM, "Authentication failed"); 871 scr_LogPrint(LPRINT_LOGNORM, "Authentication failed");
869 } 872 }
1318 1321
1319 static LmHandlerResult handle_presence(LmMessageHandler *handler, 1322 static LmHandlerResult handle_presence(LmMessageHandler *handler,
1320 LmConnection *connection, 1323 LmConnection *connection,
1321 LmMessage *m, gpointer user_data) 1324 LmMessage *m, gpointer user_data)
1322 { 1325 {
1323 char *r; 1326 char *bjid;
1324 const char *from, *rname, *p=NULL, *ustmsg=NULL; 1327 const char *from, *rname, *p=NULL, *ustmsg=NULL;
1325 enum imstatus ust; 1328 enum imstatus ust;
1326 char bpprio; 1329 char bpprio;
1327 time_t timestamp = 0L; 1330 time_t timestamp = 0L;
1328 LmMessageNode *muc_packet, *caps; 1331 LmMessageNode *muc_packet, *caps;
1342 if (self_fjid && !strcasecmp(self_fjid, from)) { 1345 if (self_fjid && !strcasecmp(self_fjid, from)) {
1343 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; // Ignoring self presence 1346 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; // Ignoring self presence
1344 } 1347 }
1345 } 1348 }
1346 1349
1347 r = jidtodisp(from); 1350 bjid = jidtodisp(from);
1348 mstype = lm_message_get_sub_type(m); 1351 mstype = lm_message_get_sub_type(m);
1349 1352
1350 if (mstype == LM_MESSAGE_SUB_TYPE_ERROR) { 1353 if (mstype == LM_MESSAGE_SUB_TYPE_ERROR) {
1351 LmMessageNode *x; 1354 LmMessageNode *x;
1352 scr_LogPrint(LPRINT_LOGNORM, "Error presence packet from <%s>", r); 1355 scr_LogPrint(LPRINT_LOGNORM, "Error presence packet from <%s>", bjid);
1353 x = lm_message_node_find_child(m->node, "error"); 1356 x = lm_message_node_find_child(m->node, "error");
1354 display_server_error(x); 1357 display_server_error(x);
1355 // Let's check it isn't a nickname conflict. 1358 // Let's check it isn't a nickname conflict.
1356 // XXX Note: We should handle the <conflict/> string condition. 1359 // XXX Note: We should handle the <conflict/> string condition.
1357 if ((p = lm_message_node_get_attribute(x, "code")) != NULL) { 1360 if ((p = lm_message_node_get_attribute(x, "code")) != NULL) {
1358 if (atoi(p) == 409) { 1361 if (atoi(p) == 409) {
1359 // 409 = conflict (nickname is in use or registered by another user) 1362 // 409 = conflict (nickname is in use or registered by another user)
1360 // If we are not inside this room, we should reset the nickname 1363 // If we are not inside this room, we should reset the nickname
1361 GSList *room_elt = roster_find(r, jidsearch, 0); 1364 GSList *room_elt = roster_find(bjid, jidsearch, 0);
1362 if (room_elt && !buddy_getinsideroom(room_elt->data)) 1365 if (room_elt && !buddy_getinsideroom(room_elt->data))
1363 buddy_setnickname(room_elt->data, NULL); 1366 buddy_setnickname(room_elt->data, NULL);
1364 } 1367 }
1365 } 1368 }
1366 1369
1367 g_free(r); 1370 g_free(bjid);
1368 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; 1371 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
1369 } 1372 }
1370 1373
1371 p = lm_message_node_get_child_value(m->node, "priority"); 1374 p = lm_message_node_get_child_value(m->node, "priority");
1372 if (p && *p) bpprio = (gchar)atoi(p); 1375 if (p && *p) bpprio = (gchar)atoi(p);
1390 // Timestamp? 1393 // Timestamp?
1391 timestamp = lm_message_node_get_timestamp(m->node); 1394 timestamp = lm_message_node_get_timestamp(m->node);
1392 1395
1393 if (muc_packet) { 1396 if (muc_packet) {
1394 // This is a MUC presence message 1397 // This is a MUC presence message
1395 handle_muc_presence(from, muc_packet, r, rname, 1398 handle_muc_presence(from, muc_packet, bjid, rname,
1396 ust, ustmsg, timestamp, bpprio); 1399 ust, ustmsg, timestamp, bpprio);
1397 } else { 1400 } else {
1398 // Not a MUC message, so this is a regular buddy... 1401 // Not a MUC message, so this is a regular buddy...
1399 // Call hk_statuschange() if status has changed or if the 1402 // Call hk_statuschange() if status has changed or if the
1400 // status message is different 1403 // status message is different
1401 const char *msg; 1404 const char *msg;
1402 msg = roster_getstatusmsg(r, rname); 1405 msg = roster_getstatusmsg(bjid, rname);
1403 if ((ust != roster_getstatus(r, rname)) || 1406 if ((ust != roster_getstatus(bjid, rname)) ||
1404 (!ustmsg && msg && msg[0]) || 1407 (!ustmsg && msg && msg[0]) ||
1405 (ustmsg && (!msg || strcmp(ustmsg, msg))) || 1408 (ustmsg && (!msg || strcmp(ustmsg, msg))) ||
1406 (bpprio != roster_getprio(r, rname))) 1409 (bpprio != roster_getprio(bjid, rname)))
1407 hk_statuschange(r, rname, bpprio, timestamp, ust, ustmsg); 1410 hk_statuschange(bjid, rname, bpprio, timestamp, ust, ustmsg);
1408 // Presence signature processing 1411 // Presence signature processing
1409 if (!ustmsg) 1412 if (!ustmsg)
1410 ustmsg = ""; // Some clients omit the <status/> element :-( 1413 ustmsg = ""; // Some clients omit the <status/> element :-(
1411 check_signature(r, rname, lm_message_node_find_xmlns(m->node, NS_SIGNED), 1414 check_signature(bjid, rname,
1412 ustmsg); 1415 lm_message_node_find_xmlns(m->node, NS_SIGNED), ustmsg);
1413 } 1416 }
1414 1417
1415 // XEP-0115 Entity Capabilities 1418 // XEP-0115 Entity Capabilities
1416 caps = lm_message_node_find_xmlns(m->node, NS_CAPS); 1419 caps = lm_message_node_find_xmlns(m->node, NS_CAPS);
1417 if (caps && ust != offline) { 1420 if (caps && ust != offline) {
1418 const char *ver = lm_message_node_get_attribute(caps, "ver"); 1421 const char *ver = lm_message_node_get_attribute(caps, "ver");
1419 GSList *sl_buddy = NULL; 1422 GSList *sl_buddy = NULL;
1420 if (rname) 1423 if (rname)
1421 sl_buddy = roster_find(r, jidsearch, ROSTER_TYPE_USER); 1424 sl_buddy = roster_find(bjid, jidsearch, ROSTER_TYPE_USER);
1422 // Only cache the caps if the user is on the roster 1425 // Only cache the caps if the user is on the roster
1423 if (sl_buddy && buddy_getonserverflag(sl_buddy->data)) { 1426 if (sl_buddy && buddy_getonserverflag(sl_buddy->data)) {
1424 buddy_resource_setcaps(sl_buddy->data, rname, ver); 1427 buddy_resource_setcaps(sl_buddy->data, rname, ver);
1425 1428
1426 if (!caps_has_hash(ver)) { 1429 if (!caps_has_hash(ver)) {
1443 lm_message_handler_unref(handler); 1446 lm_message_handler_unref(handler);
1444 } 1447 }
1445 } 1448 }
1446 } 1449 }
1447 1450
1448 g_free(r); 1451 g_free(bjid);
1449 return LM_HANDLER_RESULT_REMOVE_MESSAGE; 1452 return LM_HANDLER_RESULT_REMOVE_MESSAGE;
1450 } 1453 }
1451 1454
1452 1455
1453 static LmHandlerResult handle_iq(LmMessageHandler *handler, 1456 static LmHandlerResult handle_iq(LmMessageHandler *handler,