Mercurial > ~mikael > mcabber > hg
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 |