# HG changeset patch # User Mikael Berthe # Date 1148414758 -7200 # Node ID a7b3409df6bc294db0fd5ab2c88052b554bd5181 # Parent 4f1a93faffea89a7f67f696799133f1d07c234a7 MUC: Work around user server restart When receiving a suspicious groupchat message/presence, from a room we're not a member of, send an unavailable presence message. Thanks to pmw for the report, thanks to hawke (from jdev) for the workaround suggestion. diff -r 4f1a93faffea -r a7b3409df6bc mcabber/src/jabglue.c --- a/mcabber/src/jabglue.c Tue May 23 21:38:27 2006 +0200 +++ b/mcabber/src/jabglue.c Tue May 23 22:05:58 2006 +0200 @@ -794,6 +794,37 @@ rname = strchr(from, '/'); if (rname) rname++; + // Check for unexpected groupchat messages + // If we receive a groupchat message from a room we're not a member of, + // this is probably a server issue and the best we can do is to send + // a type unavailable. + if (type && !strcmp(type, "groupchat") && !roster_getnickname(jid)) { + // It shouldn't happen, probably a server issue + GSList *room_elt; + char *mbuf; + + mbuf = g_strdup_printf("Unexpected groupchat packet!"); + scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf); + scr_WriteIncomingMessage(jid, mbuf, 0, HBB_PREFIX_INFO); + g_free(mbuf); + + // Send back an unavailable packet + jb_setstatus(offline, jid, ""); + + // MUC + // Make sure this is a room (it can be a conversion user->room) + room_elt = roster_find(jid, jidsearch, 0); + if (!room_elt) { + room_elt = roster_add_user(jid, NULL, NULL, ROSTER_TYPE_ROOM, sub_none); + } else { + buddy_settype(room_elt->data, ROSTER_TYPE_ROOM); + } + + buddylist_build(); + scr_DrawRoster(); + return; + } + // We don't call the message_in hook if 'block_unsubscribed' is true and // this is a regular message from an unsubscribed user. if (!settings_opt_get_int("block_unsubscribed") || @@ -978,7 +1009,8 @@ { xmlnode y; char *p; - const char *m; + char *mbuf; + const char *ournick; enum imrole mbrole = role_none; enum imaffiliation mbaffil = affil_none; const char *mbjid = NULL, *mbnick = NULL; @@ -992,8 +1024,11 @@ room_elt = roster_find(roomjid, jidsearch, 0); if (!room_elt) { - // Add room if it doesn't already exist FIXME shouldn't happen! + // Add room if it doesn't already exist + // It shouldn't happen, there is probably something wrong (server or + // network issue?) room_elt = roster_add_user(roomjid, NULL, NULL, ROSTER_TYPE_ROOM, sub_none); + scr_LogPrint(LPRINT_LOGNORM, "Strange MUC presence message"); } else { // Make sure this is a room (it can be a conversion user->room) buddy_settype(room_elt->data, ROSTER_TYPE_ROOM); @@ -1031,6 +1066,23 @@ actorjid = xmlnode_get_attrib(z, "jid"); } + // Get our room nickname + ournick = buddy_getnickname(room_elt->data); + + if (!ournick) { + // It shouldn't happen, probably a server issue + mbuf = g_strdup_printf("Unexpected groupchat packet!"); + + scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf); + scr_WriteIncomingMessage(roomjid, mbuf, 0, HBB_PREFIX_INFO); + g_free(mbuf); + // Send back an unavailable packet + jb_setstatus(offline, roomjid, ""); + buddylist_build(); + scr_DrawRoster(); + return; + } + // Get the status code // 201: a room has been created // 301: the user has been banned from the room @@ -1046,7 +1098,6 @@ // Check for nickname change if (statuscode == 303 && mbnick) { - gchar *mbuf; mbuf = g_strdup_printf("%s is now known as %s", rname, mbnick); scr_WriteIncomingMessage(roomjid, mbuf, usttime, HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG); @@ -1054,14 +1105,12 @@ g_free(mbuf); buddy_resource_setname(room_elt->data, rname, mbnick); // Maybe it's _our_ nickname... - m = buddy_getnickname(room_elt->data); - if (m && !strcmp(rname, m)) + if (ournick && !strcmp(rname, ournick)) buddy_setnickname(room_elt->data, mbnick); } // Check for departure/arrival if (!mbnick && mbrole == role_none) { - gchar *mbuf; enum { leave=0, kick, ban } how = leave; bool we_left = FALSE; @@ -1071,9 +1120,7 @@ how = ban; // If this is a leave, check if it is ourself - m = buddy_getnickname(room_elt->data); - - if (m && !strcmp(rname, m)) { + if (ournick && !strcmp(rname, ournick)) { we_left = TRUE; // _We_ have left! (kicked, banned, etc.) buddy_setinsideroom(room_elt->data, FALSE); buddy_setnickname(room_elt->data, NULL); @@ -1146,20 +1193,6 @@ g_free(mbuf); } else if (buddy_getstatus(room_elt->data, rname) == offline && ust != offline) { - gchar *mbuf; - const char *ournick = buddy_getnickname(room_elt->data); - - if (!ournick) { - // I think it shouldn't happen, but let's put a warning for a while... - mbuf = g_strdup_printf("MUC ERR: you have no nickname, " - "please send a bug report!"); - scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf); - scr_WriteIncomingMessage(roomjid, mbuf, 0, HBB_PREFIX_INFO); - g_free(mbuf); - buddylist_build(); - scr_DrawRoster(); - return; - } if (!buddy_getinsideroom(room_elt->data)) { // We weren't inside the room yet. Now we are.