diff options
Diffstat (limited to 'src/mod_muc')
-rw-r--r-- | src/mod_muc/mod_muc.erl | 123 | ||||
-rw-r--r-- | src/mod_muc/mod_muc_room.erl | 291 |
2 files changed, 222 insertions, 192 deletions
diff --git a/src/mod_muc/mod_muc.erl b/src/mod_muc/mod_muc.erl index 5ebecf720..b3112472d 100644 --- a/src/mod_muc/mod_muc.erl +++ b/src/mod_muc/mod_muc.erl @@ -107,7 +107,7 @@ do_route1(Host, ServerHost, Access, From, To, Packet) -> "iq" -> case jlib:iq_query_info(Packet) of #iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS, - sub_el = SubEl} = IQ -> + sub_el = _SubEl} = IQ -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], @@ -123,7 +123,7 @@ do_route1(Host, ServerHost, Access, From, To, Packet) -> #iq{type = get, xmlns = ?NS_REGISTER = XMLNS, lang = Lang, - sub_el = SubEl} = IQ -> + sub_el = _SubEl} = IQ -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "query", @@ -155,7 +155,7 @@ do_route1(Host, ServerHost, Access, From, To, Packet) -> #iq{type = get, xmlns = ?NS_VCARD = XMLNS, lang = Lang, - sub_el = SubEl} = IQ -> + sub_el = _SubEl} = IQ -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "vCard", @@ -380,76 +380,81 @@ iq_get_register_info(Host, From, Lang) -> Lang, "Enter nickname you want to register")}]}, ?XFIELD("text-single", "Nickname", "nick", Nick)]}]. -iq_set_register_info(Host, From, XData, Lang) -> +iq_set_register_info(Host, From, Nick, Lang) -> {LUser, LServer, _} = jlib:jid_tolower(From), LUS = {LUser, LServer}, - case lists:keysearch("nick", 1, XData) of - false -> - ErrText = "You must fill in field \"nick\" in the form", - {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)}; - {value, {_, [Nick]}} -> - F = fun() -> - case Nick of - "" -> - mnesia:delete({muc_registered, {LUS, Host}}), + F = fun() -> + case Nick of + "" -> + mnesia:delete({muc_registered, {LUS, Host}}), + ok; + _ -> + Allow = + case mnesia:select( + muc_registered, + [{#muc_registered{us_host = '$1', + nick = Nick, + _ = '_'}, + [{'==', {element, 2, '$1'}, Host}], + ['$_']}]) of + [] -> + true; + [#muc_registered{us_host = {U, _Host}}] -> + U == LUS + end, + if + Allow -> + mnesia:write( + #muc_registered{us_host = {LUS, Host}, + nick = Nick}), ok; - _ -> - Allow = - case mnesia:select( - muc_registered, - [{#muc_registered{us_host = '$1', - nick = Nick, - _ = '_'}, - [{'==', {element, 2, '$1'}, Host}], - ['$_']}]) of - [] -> - true; - [#muc_registered{us_host = {U, _Host}}] -> - U == LUS - end, - if - Allow -> - mnesia:write( - #muc_registered{us_host = {LUS, Host}, - nick = Nick}), - ok; - true -> - false - end + true -> + false end - end, - case mnesia:transaction(F) of - {atomic, ok} -> - {result, []}; - {atomic, false} -> - ErrText = "Specified nickname is already registered", - {error, ?ERRT_CONFLICT(Lang, ErrText)}; - _ -> - {error, ?ERR_INTERNAL_SERVER_ERROR} - end + end + end, + case mnesia:transaction(F) of + {atomic, ok} -> + {result, []}; + {atomic, false} -> + ErrText = "Specified nickname is already registered", + {error, ?ERRT_CONFLICT(Lang, ErrText)}; + _ -> + {error, ?ERR_INTERNAL_SERVER_ERROR} end. process_iq_register_set(Host, From, SubEl, Lang) -> {xmlelement, _Name, _Attrs, Els} = SubEl, - case xml:remove_cdata(Els) of - [{xmlelement, "x", _Attrs1, _Els1} = XEl] -> - case {xml:get_tag_attr_s("xmlns", XEl), - xml:get_tag_attr_s("type", XEl)} of - {?NS_XDATA, "cancel"} -> - {result, []}; - {?NS_XDATA, "submit"} -> - XData = jlib:parse_xdata_submit(XEl), - case XData of - invalid -> - {error, ?ERR_BAD_REQUEST}; + case xml:get_subtag(SubEl, "remove") of + false -> + case xml:remove_cdata(Els) of + [{xmlelement, "x", _Attrs1, _Els1} = XEl] -> + case {xml:get_tag_attr_s("xmlns", XEl), + xml:get_tag_attr_s("type", XEl)} of + {?NS_XDATA, "cancel"} -> + {result, []}; + {?NS_XDATA, "submit"} -> + XData = jlib:parse_xdata_submit(XEl), + case XData of + invalid -> + {error, ?ERR_BAD_REQUEST}; + _ -> + case lists:keysearch("nick", 1, XData) of + false -> + ErrText = "You must fill in field \"Nickname\" in the form", + {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)}; + {value, {_, [Nick]}} -> + iq_set_register_info(Host, From, Nick, Lang) + end + end; _ -> - iq_set_register_info(Host, From, XData, Lang) + {error, ?ERR_BAD_REQUEST} end; _ -> {error, ?ERR_BAD_REQUEST} end; _ -> - {error, ?ERR_BAD_REQUEST} + iq_set_register_info(Host, From, "", Lang) end. iq_get_vcard(Lang) -> diff --git a/src/mod_muc/mod_muc_room.erl b/src/mod_muc/mod_muc_room.erl index 15bacbfe2..9cbdc6874 100644 --- a/src/mod_muc/mod_muc_room.erl +++ b/src/mod_muc/mod_muc_room.erl @@ -101,7 +101,7 @@ start(Host, ServerHost, Access, Room, Opts) -> %% ignore | %% {stop, StopReason} %%---------------------------------------------------------------------- -init([Host, ServerHost, Access, Room, Creator, Nick]) -> +init([Host, ServerHost, Access, Room, Creator, _Nick]) -> State = set_affiliation(Creator, owner, #state{host = Host, server_host = ServerHost, @@ -559,16 +559,11 @@ normal_state({route, From, ToNick, end, {next_state, normal_state, StateData}; -normal_state(Event, StateData) -> +normal_state(_Event, StateData) -> {next_state, normal_state, StateData}. - - - - - %%---------------------------------------------------------------------- %% Func: handle_event/3 %% Returns: {next_state, NextStateName, NextStateData} | @@ -862,15 +857,13 @@ filter_presence({xmlelement, "presence", Attrs, Els}) -> case El of {xmlcdata, _} -> false; - {xmlelement, Name1, Attrs1, _Els1} -> + {xmlelement, _Name1, Attrs1, _Els1} -> XMLNS = xml:get_attr_s("xmlns", Attrs1), - case {Name1, XMLNS} of - {"show", ""} -> - true; - {"status", ""} -> - true; + case XMLNS of + ?NS_MUC ++ _ -> + false; _ -> - false + true end end end, Els), @@ -971,6 +964,20 @@ add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) -> add_user_presence( From, Packet, add_online_user(From, Nick, Role, StateData)), + if not (NewState#state.config)#config.anonymous -> + WPacket = {xmlelement, "message", [{"type", "groupchat"}], + [{xmlelement, "body", [], + [{xmlcdata, translate:translate( + Lang, + "This room is not anonymous")}]}, + {xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], + [{xmlelement, "status", [{"code", "100"}], []}]}]}, + ejabberd_router:route( + StateData#state.jid, + From, WPacket); + true -> + ok + end, send_new_presence(From, NewState), send_existing_presences(From, NewState), Shift = count_stanza_shift(Nick, Els, NewState), @@ -1550,23 +1557,23 @@ process_admin_items_set(UJID, Items, Lang, StateData) -> set_affiliation_and_reason( JID, outcast, Reason, set_role(JID, none, SD)); - {JID, affiliation, A, Reason} when + {JID, affiliation, A, _Reason} when (A == admin) or (A == owner) -> SD1 = set_affiliation(JID, A, SD), SD2 = set_role(JID, moderator, SD1), send_update_presence(JID, SD2), SD2; - {JID, affiliation, member, Reason} -> + {JID, affiliation, member, _Reason} -> SD1 = set_affiliation( JID, member, SD), SD2 = set_role(JID, participant, SD1), send_update_presence(JID, SD2), SD2; - {JID, role, R, Reason} -> + {JID, role, R, _Reason} -> SD1 = set_role(JID, R, SD), catch send_new_presence(JID, SD1), SD1; - {JID, affiliation, A, Reason} -> + {JID, affiliation, A, _Reason} -> SD1 = set_affiliation(JID, A, SD), send_update_presence(JID, SD1), SD1 @@ -1593,7 +1600,7 @@ process_admin_items_set(UJID, Items, Lang, StateData) -> end. -find_changed_items(UJID, UAffiliation, URole, [], _Lang, StateData, Res) -> +find_changed_items(_UJID, _UAffiliation, _URole, [], _Lang, _StateData, Res) -> {result, Res}; find_changed_items(UJID, UAffiliation, URole, [{xmlcdata, _} | Items], Lang, StateData, Res) -> @@ -1721,143 +1728,143 @@ find_changed_items(_UJID, _UAffiliation, _URole, _Items, {error, ?ERR_BAD_REQUEST}. -can_change_ra(FAffiliation, FRole, - TAffiliation, TRole, +can_change_ra(_FAffiliation, _FRole, + TAffiliation, _TRole, affiliation, Value) when (TAffiliation == Value) -> nothing; -can_change_ra(FAffiliation, FRole, - TAffiliation, TRole, +can_change_ra(_FAffiliation, _FRole, + _TAffiliation, TRole, role, Value) when (TRole == Value) -> nothing; -can_change_ra(FAffiliation, FRole, - outcast, TRole, +can_change_ra(FAffiliation, _FRole, + outcast, _TRole, affiliation, none) when (FAffiliation == owner) or (FAffiliation == admin) -> true; -can_change_ra(FAffiliation, FRole, - outcast, TRole, +can_change_ra(FAffiliation, _FRole, + outcast, _TRole, affiliation, member) when (FAffiliation == owner) or (FAffiliation == admin) -> true; -can_change_ra(owner, FRole, - outcast, TRole, +can_change_ra(owner, _FRole, + outcast, _TRole, affiliation, admin) -> true; -can_change_ra(owner, FRole, - outcast, TRole, +can_change_ra(owner, _FRole, + outcast, _TRole, affiliation, owner) -> true; -can_change_ra(FAffiliation, FRole, - none, TRole, +can_change_ra(FAffiliation, _FRole, + none, _TRole, affiliation, outcast) when (FAffiliation == owner) or (FAffiliation == admin) -> true; -can_change_ra(FAffiliation, FRole, - none, TRole, +can_change_ra(FAffiliation, _FRole, + none, _TRole, affiliation, member) when (FAffiliation == owner) or (FAffiliation == admin) -> true; -can_change_ra(owner, FRole, - none, TRole, +can_change_ra(owner, _FRole, + none, _TRole, affiliation, admin) -> true; -can_change_ra(owner, FRole, - none, TRole, +can_change_ra(owner, _FRole, + none, _TRole, affiliation, owner) -> true; -can_change_ra(FAffiliation, FRole, - member, TRole, +can_change_ra(FAffiliation, _FRole, + member, _TRole, affiliation, outcast) when (FAffiliation == owner) or (FAffiliation == admin) -> true; -can_change_ra(FAffiliation, FRole, - member, TRole, +can_change_ra(FAffiliation, _FRole, + member, _TRole, affiliation, none) when (FAffiliation == owner) or (FAffiliation == admin) -> true; -can_change_ra(owner, FRole, - member, TRole, +can_change_ra(owner, _FRole, + member, _TRole, affiliation, admin) -> true; -can_change_ra(owner, FRole, - member, TRole, +can_change_ra(owner, _FRole, + member, _TRole, affiliation, owner) -> true; -can_change_ra(owner, FRole, - admin, TRole, +can_change_ra(owner, _FRole, + admin, _TRole, affiliation, _Affiliation) -> true; -can_change_ra(owner, FRole, - owner, TRole, +can_change_ra(owner, _FRole, + owner, _TRole, affiliation, _Affiliation) -> true; -can_change_ra(FAffiliation, FRole, - TAffiliation, TRole, - affiliation, Value) -> +can_change_ra(_FAffiliation, _FRole, + _TAffiliation, _TRole, + affiliation, _Value) -> false; -can_change_ra(FAffiliation, moderator, - TAffiliation, visitor, +can_change_ra(_FAffiliation, moderator, + _TAffiliation, visitor, role, none) -> true; -can_change_ra(FAffiliation, moderator, - TAffiliation, visitor, +can_change_ra(_FAffiliation, moderator, + _TAffiliation, visitor, role, participant) -> true; -can_change_ra(FAffiliation, FRole, - TAffiliation, visitor, +can_change_ra(FAffiliation, _FRole, + _TAffiliation, visitor, role, moderator) when (FAffiliation == owner) or (FAffiliation == admin) -> true; -can_change_ra(FAffiliation, moderator, - TAffiliation, participant, +can_change_ra(_FAffiliation, moderator, + _TAffiliation, participant, role, none) -> true; -can_change_ra(FAffiliation, moderator, - TAffiliation, participant, +can_change_ra(_FAffiliation, moderator, + _TAffiliation, participant, role, visitor) -> true; -can_change_ra(FAffiliation, FRole, - TAffiliation, participant, +can_change_ra(FAffiliation, _FRole, + _TAffiliation, participant, role, moderator) when (FAffiliation == owner) or (FAffiliation == admin) -> true; -can_change_ra(FAffiliation, FRole, +can_change_ra(_FAffiliation, _FRole, owner, moderator, role, visitor) -> false; -can_change_ra(owner, FRole, - TAffiliation, moderator, +can_change_ra(owner, _FRole, + _TAffiliation, moderator, role, visitor) -> true; -can_change_ra(FAffiliation, FRole, +can_change_ra(_FAffiliation, _FRole, admin, moderator, role, visitor) -> false; -can_change_ra(admin, FRole, - TAffiliation, moderator, +can_change_ra(admin, _FRole, + _TAffiliation, moderator, role, visitor) -> true; -can_change_ra(FAffiliation, FRole, +can_change_ra(_FAffiliation, _FRole, owner, moderator, role, participant) -> false; -can_change_ra(owner, FRole, - TAffiliation, moderator, +can_change_ra(owner, _FRole, + _TAffiliation, moderator, role, participant) -> true; -can_change_ra(FAffiliation, FRole, +can_change_ra(_FAffiliation, _FRole, admin, moderator, role, participant) -> false; -can_change_ra(admin, FRole, - TAffiliation, moderator, +can_change_ra(admin, _FRole, + _TAffiliation, moderator, role, participant) -> true; -can_change_ra(FAffiliation, FRole, - TAffiliation, TRole, - role, Value) -> +can_change_ra(_FAffiliation, _FRole, + _TAffiliation, _TRole, + role, _Value) -> false. @@ -1887,13 +1894,13 @@ send_kickban_presence(JID, Reason, Code, StateData) -> end, LJIDs). send_kickban_presence1(UJID, Reason, Code, StateData) -> - {ok, #user{jid = RealJID, + {ok, #user{jid = _RealJID, nick = Nick}} = ?DICT:find(jlib:jid_tolower(UJID), StateData#state.users), Affiliation = get_affiliation(UJID, StateData), SAffiliation = affiliation_to_list(Affiliation), lists:foreach( - fun({LJID, Info}) -> + fun({_LJID, Info}) -> ItemAttrs = [{"affiliation", SAffiliation}, {"role", "none"}], ItemEls = case Reason of @@ -1922,9 +1929,9 @@ process_iq_owner(From, set, Lang, SubEl, StateData) -> FAffiliation = get_affiliation(From, StateData), case FAffiliation of owner -> - {xmlelement, Name, Attrs, Els} = SubEl, + {xmlelement, _Name, _Attrs, Els} = SubEl, case xml:remove_cdata(Els) of - [{xmlelement, "x", Attrs1, Els1} = XEl] -> + [{xmlelement, "x", _Attrs1, _Els1} = XEl] -> case {xml:get_tag_attr_s("xmlns", XEl), xml:get_tag_attr_s("type", XEl)} of {?NS_XDATA, "cancel"} -> @@ -1934,8 +1941,8 @@ process_iq_owner(From, set, Lang, SubEl, StateData) -> _ -> {error, ?ERR_BAD_REQUEST} end; - [{xmlelement, "destroy", Attrs1, Els1}] -> - destroy_room(Els1, StateData); + [{xmlelement, "destroy", _Attrs1, _Els1} = SubEl1] -> + destroy_room(SubEl1, StateData); Items -> process_admin_items_set(From, Items, Lang, StateData) end; @@ -1948,7 +1955,7 @@ process_iq_owner(From, get, Lang, SubEl, StateData) -> FAffiliation = get_affiliation(From, StateData), case FAffiliation of owner -> - {xmlelement, Name, Attrs, Els} = SubEl, + {xmlelement, _Name, _Attrs, Els} = SubEl, case xml:remove_cdata(Els) of [] -> get_config(Lang, StateData); @@ -2009,39 +2016,18 @@ get_config(Lang, StateData) -> [{xmlcdata, translate:translate(Lang, "Configuration for ") ++ jlib:jid_to_string(StateData#state.jid)}]}, ?STRINGXFIELD("Room title", - "title", - Config#config.title), - ?BOOLXFIELD("Allow users to change subject?", - "allow_change_subj", - Config#config.allow_change_subj), - ?BOOLXFIELD("Allow users to query other users?", - "allow_query_users", - Config#config.allow_query_users), - ?BOOLXFIELD("Allow users to send private messages?", - "allow_private_messages", - Config#config.allow_private_messages), - ?BOOLXFIELD("Make room public searchable?", + "title", + Config#config.title), + ?BOOLXFIELD("Make room persistent", + "persistent", + Config#config.persistent), + ?BOOLXFIELD("Make room public searchable", "public", Config#config.public), - ?BOOLXFIELD("Make participants list public?", + ?BOOLXFIELD("Make participants list public", "public_list", Config#config.public_list), - ?BOOLXFIELD("Make room persistent?", - "persistent", - Config#config.persistent), - ?BOOLXFIELD("Make room moderated?", - "moderated", - Config#config.moderated), - ?BOOLXFIELD("Default users as members?", - "members_by_default", - Config#config.members_by_default), - ?BOOLXFIELD("Make room members only?", - "members_only", - Config#config.members_only), - ?BOOLXFIELD("Allow users to send invites?", - "allow_user_invites", - Config#config.allow_user_invites), - ?BOOLXFIELD("Make room password protected?", + ?BOOLXFIELD("Make room password protected", "password_protected", Config#config.password_protected), ?PRIVATEXFIELD("Password", @@ -2050,10 +2036,31 @@ get_config(Lang, StateData) -> true -> Config#config.password; false -> "" end), - ?BOOLXFIELD("Make room anonymous?", + ?BOOLXFIELD("Make room semianonymous", "anonymous", Config#config.anonymous), - ?BOOLXFIELD("Enable logging?", + ?BOOLXFIELD("Make room members-only", + "members_only", + Config#config.members_only), + ?BOOLXFIELD("Make room moderated", + "moderated", + Config#config.moderated), + ?BOOLXFIELD("Default users as participants", + "members_by_default", + Config#config.members_by_default), + ?BOOLXFIELD("Allow users to change subject", + "allow_change_subj", + Config#config.allow_change_subj), + ?BOOLXFIELD("Allow users to send private messages", + "allow_private_messages", + Config#config.allow_private_messages), + ?BOOLXFIELD("Allow users to query other users", + "allow_query_users", + Config#config.allow_query_users), + ?BOOLXFIELD("Allow users to send invites", + "allow_user_invites", + Config#config.allow_user_invites), + ?BOOLXFIELD("Enable logging", "logging", Config#config.logging) ], @@ -2125,7 +2132,7 @@ set_xoption([{"anonymous", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(anonymous, Val); set_xoption([{"logging", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(logging, Val); -set_xoption([_ | Opts], Config) -> +set_xoption([_ | _Opts], _Config) -> {error, ?ERR_BAD_REQUEST}. @@ -2203,17 +2210,15 @@ make_opts(StateData) -> -destroy_room(DEls, StateData) -> +destroy_room(DEl, StateData) -> lists:foreach( - fun({LJID, Info}) -> + fun({_LJID, Info}) -> Nick = Info#user.nick, ItemAttrs = [{"affiliation", "none"}, {"role", "none"}], Packet = {xmlelement, "presence", [{"type", "unavailable"}], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], - [{xmlelement, "item", ItemAttrs, []}, - {xmlelement, "destroy", [], - DEls}]}]}, + [{xmlelement, "item", ItemAttrs, []}, DEl]}]}, ejabberd_router:route( jlib:jid_replace_resource(StateData#state.jid, Nick), Info#user.jid, @@ -2243,10 +2248,10 @@ destroy_room(DEls, StateData) -> ?FEATURE(Fiffalse) end). -process_iq_disco_info(From, set, Lang, StateData) -> +process_iq_disco_info(_From, set, _Lang, _StateData) -> {error, ?ERR_NOT_ALLOWED}; -process_iq_disco_info(From, get, Lang, StateData) -> +process_iq_disco_info(_From, get, Lang, StateData) -> Config = StateData#state.config, {result, [{xmlelement, "identity", [{"category", "conference"}, @@ -2266,13 +2271,33 @@ process_iq_disco_info(From, get, Lang, StateData) -> "muc_moderated", "muc_unmoderated"), ?CONFIG_OPT_TO_FEATURE(Config#config.password_protected, "muc_passwordprotected", "muc_unsecured") - ], StateData}. + ] ++ iq_disco_info_extras(Lang, StateData), StateData}. + +-define(RFIELDT(Type, Var, Val), + {xmlelement, "field", [{"type", Type}, {"var", Var}], + [{xmlelement, "value", [], [{xmlcdata, Val}]}]}). +-define(RFIELD(Label, Var, Val), + {xmlelement, "field", [{"label", translate:translate(Lang, Label)}, + {"var", Var}], + [{xmlelement, "value", [], [{xmlcdata, Val}]}]}). -process_iq_disco_items(From, set, Lang, StateData) -> +iq_disco_info_extras(Lang, StateData) -> + Len = length(?DICT:to_list(StateData#state.users)), + [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "result"}], + [?RFIELDT("hidden", "FORM_TYPE", + "http://jabber.org/protocol/muc#roominfo"), + ?RFIELD("Description", "muc#roominfo_description", + (StateData#state.config)#config.title), + %?RFIELD("Subject", "muc#roominfo_subject", StateData#state.subject), + ?RFIELD("Number of occupants", "muc#roominfo_occupants", + integer_to_list(Len)) + ]}]. + +process_iq_disco_items(_From, set, _Lang, _StateData) -> {error, ?ERR_NOT_ALLOWED}; -process_iq_disco_items(From, get, Lang, StateData) -> +process_iq_disco_items(From, get, _Lang, StateData) -> FAffiliation = get_affiliation(From, StateData), FRole = get_role(From, StateData), case ((StateData#state.config)#config.public_list == true) orelse @@ -2282,7 +2307,7 @@ process_iq_disco_items(From, get, Lang, StateData) -> true -> UList = lists:map( - fun({LJID, Info}) -> + fun({_LJID, Info}) -> Nick = Info#user.nick, {xmlelement, "item", [{"jid", jlib:jid_to_string( @@ -2314,11 +2339,11 @@ check_invitation(From, Els, StateData) -> CanInvite = (StateData#state.config)#config.allow_user_invites orelse (FAffiliation == admin) orelse (FAffiliation == owner), case xml:remove_cdata(Els) of - [{xmlelement, "x", Attrs1, Els1} = XEl] -> + [{xmlelement, "x", _Attrs1, Els1} = XEl] -> case xml:get_tag_attr_s("xmlns", XEl) of ?NS_MUC_USER -> case xml:remove_cdata(Els1) of - [{xmlelement, "invite", Attrs2, Els2} = InviteEl] -> + [{xmlelement, "invite", Attrs2, _Els2} = InviteEl] -> case jlib:string_to_jid( xml:get_attr_s("to", Attrs2)) of error -> |