comparison mcabber/src/jabglue.c @ 864:a7b3409df6bc

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.
author Mikael Berthe <mikael@lilotux.net>
date Tue, 23 May 2006 22:05:58 +0200
parents 5ed97fc7afa0
children cee8d6be04e1
comparison
equal deleted inserted replaced
863:4f1a93faffea 864:a7b3409df6bc
791 791
792 jid = jidtodisp(from); 792 jid = jidtodisp(from);
793 793
794 rname = strchr(from, '/'); 794 rname = strchr(from, '/');
795 if (rname) rname++; 795 if (rname) rname++;
796
797 // Check for unexpected groupchat messages
798 // If we receive a groupchat message from a room we're not a member of,
799 // this is probably a server issue and the best we can do is to send
800 // a type unavailable.
801 if (type && !strcmp(type, "groupchat") && !roster_getnickname(jid)) {
802 // It shouldn't happen, probably a server issue
803 GSList *room_elt;
804 char *mbuf;
805
806 mbuf = g_strdup_printf("Unexpected groupchat packet!");
807 scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf);
808 scr_WriteIncomingMessage(jid, mbuf, 0, HBB_PREFIX_INFO);
809 g_free(mbuf);
810
811 // Send back an unavailable packet
812 jb_setstatus(offline, jid, "");
813
814 // MUC
815 // Make sure this is a room (it can be a conversion user->room)
816 room_elt = roster_find(jid, jidsearch, 0);
817 if (!room_elt) {
818 room_elt = roster_add_user(jid, NULL, NULL, ROSTER_TYPE_ROOM, sub_none);
819 } else {
820 buddy_settype(room_elt->data, ROSTER_TYPE_ROOM);
821 }
822
823 buddylist_build();
824 scr_DrawRoster();
825 return;
826 }
796 827
797 // We don't call the message_in hook if 'block_unsubscribed' is true and 828 // We don't call the message_in hook if 'block_unsubscribed' is true and
798 // this is a regular message from an unsubscribed user. 829 // this is a regular message from an unsubscribed user.
799 if (!settings_opt_get_int("block_unsubscribed") || 830 if (!settings_opt_get_int("block_unsubscribed") ||
800 (roster_getsubscription(jid) & sub_from) || 831 (roster_getsubscription(jid) & sub_from) ||
976 enum imstatus ust, char *ustmsg, 1007 enum imstatus ust, char *ustmsg,
977 time_t usttime, char bpprio) 1008 time_t usttime, char bpprio)
978 { 1009 {
979 xmlnode y; 1010 xmlnode y;
980 char *p; 1011 char *p;
981 const char *m; 1012 char *mbuf;
1013 const char *ournick;
982 enum imrole mbrole = role_none; 1014 enum imrole mbrole = role_none;
983 enum imaffiliation mbaffil = affil_none; 1015 enum imaffiliation mbaffil = affil_none;
984 const char *mbjid = NULL, *mbnick = NULL; 1016 const char *mbjid = NULL, *mbnick = NULL;
985 const char *actorjid = NULL, *reason = NULL; 1017 const char *actorjid = NULL, *reason = NULL;
986 bool new_member = FALSE; // True if somebody else joins the room (not us) 1018 bool new_member = FALSE; // True if somebody else joins the room (not us)
990 1022
991 log_muc_conf = settings_opt_get_int("log_muc_conf"); 1023 log_muc_conf = settings_opt_get_int("log_muc_conf");
992 1024
993 room_elt = roster_find(roomjid, jidsearch, 0); 1025 room_elt = roster_find(roomjid, jidsearch, 0);
994 if (!room_elt) { 1026 if (!room_elt) {
995 // Add room if it doesn't already exist FIXME shouldn't happen! 1027 // Add room if it doesn't already exist
1028 // It shouldn't happen, there is probably something wrong (server or
1029 // network issue?)
996 room_elt = roster_add_user(roomjid, NULL, NULL, ROSTER_TYPE_ROOM, sub_none); 1030 room_elt = roster_add_user(roomjid, NULL, NULL, ROSTER_TYPE_ROOM, sub_none);
1031 scr_LogPrint(LPRINT_LOGNORM, "Strange MUC presence message");
997 } else { 1032 } else {
998 // Make sure this is a room (it can be a conversion user->room) 1033 // Make sure this is a room (it can be a conversion user->room)
999 buddy_settype(room_elt->data, ROSTER_TYPE_ROOM); 1034 buddy_settype(room_elt->data, ROSTER_TYPE_ROOM);
1000 } 1035 }
1001 1036
1029 z = xmlnode_get_tag(y, "actor"); 1064 z = xmlnode_get_tag(y, "actor");
1030 if (z) 1065 if (z)
1031 actorjid = xmlnode_get_attrib(z, "jid"); 1066 actorjid = xmlnode_get_attrib(z, "jid");
1032 } 1067 }
1033 1068
1069 // Get our room nickname
1070 ournick = buddy_getnickname(room_elt->data);
1071
1072 if (!ournick) {
1073 // It shouldn't happen, probably a server issue
1074 mbuf = g_strdup_printf("Unexpected groupchat packet!");
1075
1076 scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf);
1077 scr_WriteIncomingMessage(roomjid, mbuf, 0, HBB_PREFIX_INFO);
1078 g_free(mbuf);
1079 // Send back an unavailable packet
1080 jb_setstatus(offline, roomjid, "");
1081 buddylist_build();
1082 scr_DrawRoster();
1083 return;
1084 }
1085
1034 // Get the status code 1086 // Get the status code
1035 // 201: a room has been created 1087 // 201: a room has been created
1036 // 301: the user has been banned from the room 1088 // 301: the user has been banned from the room
1037 // 303: new room nickname 1089 // 303: new room nickname
1038 // 307: the user has been kicked from the room 1090 // 307: the user has been kicked from the room
1044 statuscode = atoi(p); 1096 statuscode = atoi(p);
1045 } 1097 }
1046 1098
1047 // Check for nickname change 1099 // Check for nickname change
1048 if (statuscode == 303 && mbnick) { 1100 if (statuscode == 303 && mbnick) {
1049 gchar *mbuf;
1050 mbuf = g_strdup_printf("%s is now known as %s", rname, mbnick); 1101 mbuf = g_strdup_printf("%s is now known as %s", rname, mbnick);
1051 scr_WriteIncomingMessage(roomjid, mbuf, usttime, 1102 scr_WriteIncomingMessage(roomjid, mbuf, usttime,
1052 HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG); 1103 HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG);
1053 if (log_muc_conf) hlog_write_message(roomjid, 0, FALSE, mbuf); 1104 if (log_muc_conf) hlog_write_message(roomjid, 0, FALSE, mbuf);
1054 g_free(mbuf); 1105 g_free(mbuf);
1055 buddy_resource_setname(room_elt->data, rname, mbnick); 1106 buddy_resource_setname(room_elt->data, rname, mbnick);
1056 // Maybe it's _our_ nickname... 1107 // Maybe it's _our_ nickname...
1057 m = buddy_getnickname(room_elt->data); 1108 if (ournick && !strcmp(rname, ournick))
1058 if (m && !strcmp(rname, m))
1059 buddy_setnickname(room_elt->data, mbnick); 1109 buddy_setnickname(room_elt->data, mbnick);
1060 } 1110 }
1061 1111
1062 // Check for departure/arrival 1112 // Check for departure/arrival
1063 if (!mbnick && mbrole == role_none) { 1113 if (!mbnick && mbrole == role_none) {
1064 gchar *mbuf;
1065 enum { leave=0, kick, ban } how = leave; 1114 enum { leave=0, kick, ban } how = leave;
1066 bool we_left = FALSE; 1115 bool we_left = FALSE;
1067 1116
1068 if (statuscode == 307) 1117 if (statuscode == 307)
1069 how = kick; 1118 how = kick;
1070 else if (statuscode == 301) 1119 else if (statuscode == 301)
1071 how = ban; 1120 how = ban;
1072 1121
1073 // If this is a leave, check if it is ourself 1122 // If this is a leave, check if it is ourself
1074 m = buddy_getnickname(room_elt->data); 1123 if (ournick && !strcmp(rname, ournick)) {
1075
1076 if (m && !strcmp(rname, m)) {
1077 we_left = TRUE; // _We_ have left! (kicked, banned, etc.) 1124 we_left = TRUE; // _We_ have left! (kicked, banned, etc.)
1078 buddy_setinsideroom(room_elt->data, FALSE); 1125 buddy_setinsideroom(room_elt->data, FALSE);
1079 buddy_setnickname(room_elt->data, NULL); 1126 buddy_setnickname(room_elt->data, NULL);
1080 buddy_del_all_resources(room_elt->data); 1127 buddy_del_all_resources(room_elt->data);
1081 buddy_settopic(room_elt->data, NULL); 1128 buddy_settopic(room_elt->data, NULL);
1144 return; 1191 return;
1145 } 1192 }
1146 g_free(mbuf); 1193 g_free(mbuf);
1147 } else if (buddy_getstatus(room_elt->data, rname) == offline && 1194 } else if (buddy_getstatus(room_elt->data, rname) == offline &&
1148 ust != offline) { 1195 ust != offline) {
1149 gchar *mbuf;
1150 const char *ournick = buddy_getnickname(room_elt->data);
1151
1152 if (!ournick) {
1153 // I think it shouldn't happen, but let's put a warning for a while...
1154 mbuf = g_strdup_printf("MUC ERR: you have no nickname, "
1155 "please send a bug report!");
1156 scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf);
1157 scr_WriteIncomingMessage(roomjid, mbuf, 0, HBB_PREFIX_INFO);
1158 g_free(mbuf);
1159 buddylist_build();
1160 scr_DrawRoster();
1161 return;
1162 }
1163 1196
1164 if (!buddy_getinsideroom(room_elt->data)) { 1197 if (!buddy_getinsideroom(room_elt->data)) {
1165 // We weren't inside the room yet. Now we are. 1198 // We weren't inside the room yet. Now we are.
1166 // However, this could be a presence packet from another room member 1199 // However, this could be a presence packet from another room member
1167 1200