From 0313adaec6eec23531ec3365556e8ccd7426ba41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?= Date: Mon, 20 Oct 2008 10:34:00 +0000 Subject: [PATCH] Convert to exmpp. PR: EJABP-1 SVN Revision: 1663 --- ChangeLog | 5 + src/mod_irc/mod_irc.erl | 312 ++++++++++++------------- src/mod_irc/mod_irc_connection.erl | 360 +++++++++++++---------------- 3 files changed, 315 insertions(+), 362 deletions(-) diff --git a/ChangeLog b/ChangeLog index 183259f56..f46777ed2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-10-20 Jean-Sébastien Pédron + + * src/mod_irc/mod_irc.erl, src/mod_irc/mod_irc_connection.erl: Convert + to exmpp. + 2008-10-13 Jean-Sébastien Pédron * src/web/ejabberd_http.erl, src/web/ejabberd_http_poll.erl, diff --git a/src/mod_irc/mod_irc.erl b/src/mod_irc/mod_irc.erl index dd86037b9..3ef7f8ca5 100644 --- a/src/mod_irc/mod_irc.erl +++ b/src/mod_irc/mod_irc.erl @@ -40,8 +40,9 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). +-include_lib("exmpp/include/exmpp.hrl"). + -include("ejabberd.hrl"). --include("jlib.hrl"). -record(irc_connection, {jid_server_host, pid}). -record(irc_custom, {us_host, data}). @@ -193,60 +194,55 @@ do_route(Host, ServerHost, Access, From, To, Packet, DefEnc) -> allow -> do_route1(Host, ServerHost, From, To, Packet, DefEnc); _ -> - {xmlelement, _Name, Attrs, _Els} = Packet, - Lang = xml:get_attr_s("xml:lang", Attrs), - ErrText = "Access denied by service policy", - Err = jlib:make_error_reply(Packet, - ?ERRT_FORBIDDEN(Lang, ErrText)), + Lang = exmpp_stanza:get_lang(Packet), + ErrText = translate:translate(Lang, + "Access denied by service policy"), + Err = exmpp_stanza:reply_with_error(Packet, + exmpp_stanza:error(Packet#xmlel.ns, + 'forbidden', {Lang, ErrText})), ejabberd_router:route(To, From, Err) end. do_route1(Host, ServerHost, From, To, Packet, DefEnc) -> - #jid{user = ChanServ, resource = Resource} = To, - {xmlelement, _Name, _Attrs, _Els} = Packet, + #jid{node = ChanServ, resource = Resource} = To, case ChanServ of - "" -> + undefined -> case Resource of - "" -> - case jlib:iq_query_info(Packet) of - #iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS, - sub_el = _SubEl, lang = Lang} = IQ -> - Res = IQ#iq{type = result, - sub_el = [{xmlelement, "query", - [{"xmlns", XMLNS}], - iq_disco(Lang)}]}, + undefined -> + case exmpp_iq:xmlel_to_iq(Packet) of + #iq{type = get, ns = ?NS_DISCO_INFO = XMLNS, + lang = Lang} = IQ_Rec -> + Result = #xmlel{ns = XMLNS, name = 'query', + children = iq_disco(Lang)}, + Res = exmpp_iq:result(IQ_Rec, Result), ejabberd_router:route(To, From, - jlib:iq_to_xml(Res)); - #iq{type = get, xmlns = ?NS_DISCO_ITEMS = XMLNS} = IQ -> - Res = IQ#iq{type = result, - sub_el = [{xmlelement, "query", - [{"xmlns", XMLNS}], - []}]}, + exmpp_iq:iq_to_xmlel(Res)); + #iq{type = get, ns = ?NS_DISCO_ITEMS = XMLNS} = IQ_Rec -> + Result = #xmlel{ns = XMLNS, name = 'query'}, + Res = exmpp_iq:result(IQ_Rec, Result), ejabberd_router:route(To, From, - jlib:iq_to_xml(Res)); - #iq{xmlns = ?NS_REGISTER} = IQ -> - process_register(Host, From, To, DefEnc, IQ); - #iq{type = get, xmlns = ?NS_VCARD = XMLNS, - lang = Lang} = IQ -> - Res = IQ#iq{type = result, - sub_el = - [{xmlelement, "vCard", - [{"xmlns", XMLNS}], - iq_get_vcard(Lang)}]}, + exmpp_iq:iq_to_xmlel(Res)); + #iq{kind = request, ns = ?NS_INBAND_REGISTER} = IQ_Rec -> + process_register(Host, From, To, DefEnc, IQ_Rec); + #iq{type = get, ns = ?NS_VCARD = XMLNS, + lang = Lang} = IQ_Rec -> + Result = #xmlel{ns = XMLNS, name = 'vCard', + children = iq_get_vcard(Lang)}, + Res = exmpp_iq:result(IQ_Rec, Result), ejabberd_router:route(To, From, - jlib:iq_to_xml(Res)); - #iq{} = _IQ -> - Err = jlib:make_error_reply( - Packet, ?ERR_FEATURE_NOT_IMPLEMENTED), + exmpp_iq:iq_to_xmlel(Res)); + #iq{} = _IQ_Rec -> + Err = exmpp_iq:error( + Packet, 'feature-not-implemented'), ejabberd_router:route(To, From, Err); _ -> ok end; _ -> - Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST), + Err = exmpp_stanza:reply_with_error(Packet, 'bad-request'), ejabberd_router:route(To, From, Err) end; _ -> @@ -280,8 +276,8 @@ do_route1(Host, ServerHost, From, To, Packet, DefEnc) -> [[_ | _] = Nick, [_ | _] = Server] -> case ets:lookup(irc_connection, {From, Server, Host}) of [] -> - Err = jlib:make_error_reply( - Packet, ?ERR_SERVICE_UNAVAILABLE), + Err = exmpp_stanza:reply_with_error( + Packet, 'service-unavailable'), ejabberd_router:route(To, From, Err); [R] -> Pid = R#irc_connection.pid, @@ -292,8 +288,8 @@ do_route1(Host, ServerHost, From, To, Packet, DefEnc) -> ok end; _ -> - Err = jlib:make_error_reply( - Packet, ?ERR_BAD_REQUEST), + Err = exmpp_stanza:reply_with_error( + Packet, 'bad-request'), ejabberd_router:route(To, From, Err) end end @@ -305,164 +301,148 @@ closed_connection(Host, From, Server) -> iq_disco(Lang) -> - [{xmlelement, "identity", - [{"category", "conference"}, - {"type", "irc"}, - {"name", translate:translate(Lang, "IRC Transport")}], []}, - {xmlelement, "feature", - [{"var", ?NS_MUC}], []}, - {xmlelement, "feature", - [{"var", ?NS_REGISTER}], []}, - {xmlelement, "feature", - [{"var", ?NS_VCARD}], []}]. + [#xmlel{ns = ?NS_DISCO_INFO, name = 'identity', attrs = + [#xmlattr{name = 'category', value = "conference"}, + #xmlattr{name = 'type', value = "irc"}, + #xmlattr{name = 'name', value = translate:translate(Lang, "IRC Transport")}]}, + #xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs = + [#xmlattr{name = 'var', value = ?NS_MUC_s}]}, + #xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs = + [#xmlattr{name = 'var', value = ?NS_INBAND_REGISTER_s}]}, + #xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs = + [#xmlattr{name = 'var', value = ?NS_VCARD_s}]}]. iq_get_vcard(Lang) -> - [{xmlelement, "FN", [], - [{xmlcdata, "ejabberd/mod_irc"}]}, - {xmlelement, "URL", [], - [{xmlcdata, ?EJABBERD_URI}]}, - {xmlelement, "DESC", [], - [{xmlcdata, translate:translate(Lang, "ejabberd IRC module") ++ - "\nCopyright (c) 2003-2008 Alexey Shchepin"}]}]. + [#xmlel{ns = ?NS_VCARD, name = 'FN', children = + [#xmlcdata{cdata = <<"ejabberd/mod_irc">>}]}, + #xmlel{ns = ?NS_VCARD, name = 'URL', children = + [#xmlcdata{cdata = list_to_binary(?EJABBERD_URI)}]}, + #xmlel{ns = ?NS_VCARD, name = 'DESC', children = + [#xmlcdata{cdata = list_to_binary(translate:translate(Lang, "ejabberd IRC module") ++ + "\nCopyright (c) 2003-2008 Alexey Shchepin")}]}]. -process_register(Host, From, To, DefEnc, #iq{} = IQ) -> - case catch process_irc_register(Host, From, To, DefEnc, IQ) of +process_register(Host, From, To, DefEnc, #iq{} = IQ_Rec) -> + case catch process_irc_register(Host, From, To, DefEnc, IQ_Rec) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); ResIQ -> if ResIQ /= ignore -> ejabberd_router:route(To, From, - jlib:iq_to_xml(ResIQ)); + exmpp_iq:iq_to_xmlel(ResIQ)); true -> ok end end. -find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) -> +find_xdata_el(#xmlel{children = SubEls}) -> find_xdata_el1(SubEls). find_xdata_el1([]) -> false; -find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) -> - case xml:get_attr_s("xmlns", Attrs) of - ?NS_XDATA -> - {xmlelement, Name, Attrs, SubEls}; - _ -> - find_xdata_el1(Els) - end; +find_xdata_el1([#xmlel{ns = ?NS_DATA_FORMS} = El | _Els]) -> + El; find_xdata_el1([_ | Els]) -> find_xdata_el1(Els). process_irc_register(Host, From, _To, DefEnc, - #iq{type = Type, xmlns = XMLNS, - lang = Lang, sub_el = SubEl} = IQ) -> - case Type of - set -> - XDataEl = find_xdata_el(SubEl), - case XDataEl of - false -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ACCEPTABLE]}; - {xmlelement, _Name, Attrs, _SubEls} -> - case xml:get_attr_s("type", Attrs) of - "cancel" -> - IQ#iq{type = result, - sub_el = [{xmlelement, "query", - [{"xmlns", XMLNS}], []}]}; - "submit" -> - XData = jlib:parse_xdata_submit(XDataEl), - case XData of - invalid -> - IQ#iq{type = error, - sub_el = [SubEl, ?ERR_BAD_REQUEST]}; - _ -> - Node = string:tokens( - xml:get_tag_attr_s("node", SubEl), - "/"), - case set_form( - Host, From, Node, Lang, XData) of - {result, Res} -> - IQ#iq{type = result, - sub_el = [{xmlelement, "query", - [{"xmlns", XMLNS}], - Res - }]}; - {error, Error} -> - IQ#iq{type = error, - sub_el = [SubEl, Error]} - end - end; + #iq{type = get, ns = XMLNS, + lang = Lang, payload = SubEl} = IQ_Rec) -> + Node = + string:tokens(exmpp_xml:get_attribute(SubEl, 'node', ""), "/"), + case get_form(Host, From, Node, Lang ,DefEnc) of + {result, Res} -> + Result = #xmlel{ns = XMLNS, name = 'query', children = Res}, + exmpp_iq:result(IQ_Rec, Result); + {error, Error} -> + exmpp_iq:error(IQ_Rec, Error) + end; +process_irc_register(Host, From, _To, _DefEnc, + #iq{type = set, ns = XMLNS, + lang = Lang, payload = SubEl} = IQ_Rec) -> + XDataEl = find_xdata_el(SubEl), + case XDataEl of + false -> + exmpp_iq:error(IQ_Rec, 'not-acceptable'); + _ -> + case exmpp_stanza:get_type(XDataEl) of + "cancel" -> + Result = #xmlel{ns = XMLNS, name = 'query'}, + exmpp_iq:result(IQ_Rec, Result); + "submit" -> + XData = jlib:parse_xdata_submit(XDataEl), + case XData of + invalid -> + exmpp_iq:error(IQ_Rec, 'bad-request'); _ -> - IQ#iq{type = error, - sub_el = [SubEl, ?ERR_BAD_REQUEST]} - end - end; - get -> - Node = - string:tokens(xml:get_tag_attr_s("node", SubEl), "/"), - case get_form(Host, From, Node, Lang ,DefEnc) of - {result, Res} -> - IQ#iq{type = result, - sub_el = [{xmlelement, "query", - [{"xmlns", XMLNS}], - Res - }]}; - {error, Error} -> - IQ#iq{type = error, - sub_el = [SubEl, Error]} + Node = string:tokens( + exmpp_xml:get_attribute(SubEl, "node", ""), + "/"), + case set_form( + Host, From, Node, Lang, XData) of + {result, Res} -> + Result = #xmlel{ns = XMLNS, name = 'query', + children = Res}, + exmpp_iq:result(IQ_Rec, Result); + {error, Error} -> + exmpp_iq:error(IQ_Rec, Error) + end + end; + _ -> + exmpp_iq:error(IQ_Rec, 'bad-request') end end. get_form(Host, From, [], Lang, DefEnc) -> - #jid{user = User, server = Server, - luser = LUser, lserver = LServer} = From, + #jid{node = User, domain = Server, + lnode = LUser, ldomain = LServer} = From, US = {LUser, LServer}, Customs = case catch mnesia:dirty_read({irc_custom, {US, Host}}) of {'EXIT', _Reason} -> - {error, ?ERR_INTERNAL_SERVER_ERROR}; + {error, 'internal-server-error'}; [] -> {User, []}; [#irc_custom{data = Data}] -> - {xml:get_attr_s(username, Data), - xml:get_attr_s(encodings, Data)} + {proplists:get_value(username, Data, ""), + proplists:get_value(encodings, Data, "")} end, case Customs of {error, _Error} -> Customs; {Username, Encodings} -> {result, - [{xmlelement, "instructions", [], - [{xmlcdata, + [#xmlel{ns = ?NS_INBAND_REGISTER, name = 'instructions', children = + [#xmlcdata{cdata = list_to_binary( translate:translate( Lang, "You need an x:data capable client " - "to configure mod_irc settings")}]}, - {xmlelement, "x", [{"xmlns", ?NS_XDATA}], - [{xmlelement, "title", [], - [{xmlcdata, + "to configure mod_irc settings"))}]}, + #xmlel{ns = ?NS_DATA_FORMS, name = 'x', children = + [#xmlel{ns = ?NS_DATA_FORMS, name = 'title', children = + [#xmlcdata{cdata = list_to_binary( translate:translate( Lang, - "Registration in mod_irc for ") ++ User ++ "@" ++ Server}]}, - {xmlelement, "instructions", [], - [{xmlcdata, + "Registration in mod_irc for ") ++ User ++ "@" ++ Server)}]}, + #xmlel{ns = ?NS_DATA_FORMS, name = 'instructions', children = + [#xmlcdata{cdata = list_to_binary( translate:translate( Lang, "Enter username and encodings you wish to use for " - "connecting to IRC servers")}]}, - {xmlelement, "field", [{"type", "text-single"}, - {"label", + "connecting to IRC servers"))}]}, + #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [#xmlattr{name = 'type', value = "text-single"}, + #xmlattr{name = 'label', value = translate:translate( Lang, "IRC Username")}, - {"var", "username"}], - [{xmlelement, "value", [], [{xmlcdata, Username}]}]}, - {xmlelement, "field", [{"type", "fixed"}], - [{xmlelement, "value", [], - [{xmlcdata, + #xmlattr{name = 'var', value = "username"}], children = + [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(Username)}]}]}, + #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [#xmlattr{name = 'type', value = "fixed"}], children = + [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = + [#xmlcdata{cdata = list_to_binary( lists:flatten( io_lib:format( translate:translate( @@ -471,22 +451,22 @@ get_form(Host, From, [], Lang, DefEnc) -> "for IRC servers, fill this list with values " "in format '{\"irc server\", \"encoding\"}'. " "By default this service use \"~s\" encoding."), - [DefEnc]))}]}]}, - {xmlelement, "field", [{"type", "fixed"}], - [{xmlelement, "value", [], - [{xmlcdata, + [DefEnc])))}]}]}, + #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [#xmlattr{name = 'type', value = "fixed"}], children = + [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = + [#xmlcdata{cdata = list_to_binary( translate:translate( Lang, "Example: [{\"irc.lucky.net\", \"koi8-r\"}, " "{\"vendetta.fef.net\", \"iso8859-1\"}]." - )}]}]}, - {xmlelement, "field", [{"type", "text-multi"}, - {"label", + ))}]}]}, + #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [#xmlattr{name = 'type', value = "text-multi"}, + #xmlattr{name = 'label', value = translate:translate(Lang, "Encodings")}, - {"var", "encodings"}], + #xmlattr{name = 'var', value = "encodings"}], children = lists:map( fun(S) -> - {xmlelement, "value", [], [{xmlcdata, S}]} + #xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(S)}]} end, string:tokens( lists:flatten( @@ -497,13 +477,13 @@ get_form(Host, From, [], Lang, DefEnc) -> end; get_form(_Host, _, _, _Lang, _) -> - {error, ?ERR_SERVICE_UNAVAILABLE}. + {error, 'service-unavailable'}. set_form(Host, From, [], _Lang, XData) -> - {LUser, LServer, _} = jlib:jid_tolower(From), + {LUser, LServer, _} = jlib:short_prepd_jid(From), US = {LUser, LServer}, case {lists:keysearch("username", 1, XData), lists:keysearch("encodings", 1, XData)} of @@ -529,26 +509,26 @@ set_form(Host, From, [], _Lang, XData) -> {atomic, _} -> {result, []}; _ -> - {error, ?ERR_NOT_ACCEPTABLE} + {error, 'not-acceptable'} end; _ -> - {error, ?ERR_NOT_ACCEPTABLE} + {error, 'not-acceptable'} end; _ -> - {error, ?ERR_NOT_ACCEPTABLE} + {error, 'not-acceptable'} end; _ -> - {error, ?ERR_NOT_ACCEPTABLE} + {error, 'not-acceptable'} end; set_form(_Host, _, _, _Lang, _XData) -> - {error, ?ERR_SERVICE_UNAVAILABLE}. + {error, 'service-unavailable'}. get_user_and_encoding(Host, From, IRCServer, DefEnc) -> - #jid{user = User, server = _Server, - luser = LUser, lserver = LServer} = From, + #jid{node = User, domain = _Server, + lnode = LUser, ldomain = LServer} = From, US = {LUser, LServer}, case catch mnesia:dirty_read({irc_custom, {US, Host}}) of {'EXIT', _Reason} -> @@ -556,8 +536,8 @@ get_user_and_encoding(Host, From, IRCServer, DefEnc) -> [] -> {User, DefEnc}; [#irc_custom{data = Data}] -> - {xml:get_attr_s(username, Data), - case xml:get_attr_s(IRCServer, xml:get_attr_s(encodings, Data)) of + {proplists:get_value(username, Data, ""), + case proplists:get_value(IRCServer, proplists:get_value(encodings, Data, ""), "") of "" -> DefEnc; E -> E end} diff --git a/src/mod_irc/mod_irc_connection.erl b/src/mod_irc/mod_irc_connection.erl index 244f5300d..3548effa2 100644 --- a/src/mod_irc/mod_irc_connection.erl +++ b/src/mod_irc/mod_irc_connection.erl @@ -43,8 +43,9 @@ terminate/3, code_change/4]). +-include_lib("exmpp/include/exmpp.hrl"). + -include("ejabberd.hrl"). --include("jlib.hrl"). -define(SETS, gb_sets). @@ -122,8 +123,8 @@ open_socket(init, StateData) -> {error, Reason} -> ?DEBUG("connect return ~p~n", [Reason]), Text = case Reason of - timeout -> "Server Connect Timeout"; - _ -> "Server Connect Failed" + timeout -> <<"Server Connect Timeout">>; + _ -> <<"Server Connect Failed">> end, bounce_messages(Text), {stop, normal, StateData} @@ -197,22 +198,22 @@ code_change(_OldVsn, StateName, StateData, _Extra) -> %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- handle_info({route_chan, Channel, Resource, - {xmlelement, "presence", Attrs, _Els}}, - StateName, StateData) -> + El}, + StateName, StateData) when ?IS_PRESENCE(El) -> NewStateData = - case xml:get_attr_s("type", Attrs) of - "unavailable" -> + case exmpp_presence:get_type(El) of + 'unavailable' -> S1 = ?SEND(io_lib:format("PART #~s\r\n", [Channel])), S1#state{channels = dict:erase(Channel, S1#state.channels)}; - "subscribe" -> StateData; - "subscribed" -> StateData; - "unsubscribe" -> StateData; - "unsubscribed" -> StateData; - "error" -> stop; + 'subscribe' -> StateData; + 'subscribed' -> StateData; + 'unsubscribe' -> StateData; + 'unsubscribed' -> StateData; + 'error' -> stop; _ -> Nick = case Resource of - "" -> + undefined -> StateData#state.nick; _ -> Resource @@ -243,20 +244,20 @@ handle_info({route_chan, Channel, Resource, end; handle_info({route_chan, Channel, Resource, - {xmlelement, "message", Attrs, _Els} = El}, - StateName, StateData) -> + El}, + StateName, StateData) when ?IS_MESSAGE(El) -> NewStateData = - case xml:get_attr_s("type", Attrs) of - "groupchat" -> - case xml:get_path_s(El, [{elem, "subject"}, cdata]) of - "" -> + case exmpp_message:get_type(El) of + 'groupchat' -> + case exmpp_message:get_subject(El) of + undefined -> ejabberd_router:route( - jlib:make_jid( + exmpp_jid:make_jid( lists:concat( [Channel, "%", StateData#state.server]), StateData#state.host, StateData#state.nick), StateData#state.user, El), - Body = xml:get_path_s(El, [{elem, "body"}, cdata]), + Body = binary_to_list(exmpp_message:get_body(El)), case Body of "/quote " ++ Rest -> ?SEND(Rest ++ "\r\n"); @@ -309,8 +310,8 @@ handle_info({route_chan, Channel, Resource, end, Strings)), ?SEND(Res) end; - Type when Type == "chat"; Type == ""; Type == "normal" -> - Body = xml:get_path_s(El, [{elem, "body"}, cdata]), + Type when Type == 'chat'; Type == 'normal' -> + Body = binary_to_list(exmpp_message:get_body(El)), case Body of "/quote " ++ Rest -> ?SEND(Rest ++ "\r\n"); @@ -351,7 +352,7 @@ handle_info({route_chan, Channel, Resource, end, Strings)), ?SEND(Res) end; - "error" -> + 'error' -> stop; _ -> StateData @@ -365,38 +366,34 @@ handle_info({route_chan, Channel, Resource, handle_info({route_chan, Channel, Resource, - {xmlelement, "iq", _Attrs, _Els} = El}, - StateName, StateData) -> + El}, + StateName, StateData) when ?IS_IQ(El) -> From = StateData#state.user, - To = jlib:make_jid(lists:concat([Channel, "%", StateData#state.server]), + To = exmpp_jid:make_jid(lists:concat([Channel, "%", StateData#state.server]), StateData#state.host, StateData#state.nick), - case jlib:iq_query_info(El) of - #iq{xmlns = ?NS_MUC_ADMIN} = IQ -> - iq_admin(StateData, Channel, From, To, IQ); - #iq{xmlns = ?NS_VERSION} -> + case exmpp_iq:xmlel_to_iq(El) of + #iq{kind = request, ns = ?NS_MUC_ADMIN} = IQ_Rec -> + iq_admin(StateData, Channel, From, To, IQ_Rec); + #iq{kind = request, ns = ?NS_SOFT_VERSION} -> Res = io_lib:format("PRIVMSG ~s :\001VERSION\001\r\n", [Resource]), ?SEND(Res), - Err = jlib:make_error_reply( - El, ?ERR_FEATURE_NOT_IMPLEMENTED), + Err = exmpp_iq:error(El, 'feature-not-implemented'), ejabberd_router:route(To, From, Err); - #iq{xmlns = ?NS_TIME} -> + #iq{kind = request, ns = ?NS_TIME_OLD} -> Res = io_lib:format("PRIVMSG ~s :\001TIME\001\r\n", [Resource]), ?SEND(Res), - Err = jlib:make_error_reply( - El, ?ERR_FEATURE_NOT_IMPLEMENTED), + Err = exmpp_iq:error(El, 'feature-not-implemented'), ejabberd_router:route(To, From, Err); - #iq{xmlns = ?NS_VCARD} -> + #iq{kind = request, ns = ?NS_VCARD} -> Res = io_lib:format("WHOIS ~s \r\n", [Resource]), ?SEND(Res), - Err = jlib:make_error_reply( - El, ?ERR_FEATURE_NOT_IMPLEMENTED), + Err = exmpp_iq:error(El, 'feature-not-implemented'), ejabberd_router:route(To, From, Err); #iq{} -> - Err = jlib:make_error_reply( - El, ?ERR_FEATURE_NOT_IMPLEMENTED), + Err = exmpp_iq:error(El, 'feature-not-implemented'), ejabberd_router:route(To, From, Err); _ -> ok @@ -408,12 +405,12 @@ handle_info({route_chan, _Channel, _Resource, _Packet}, StateName, StateData) -> handle_info({route_nick, Nick, - {xmlelement, "message", Attrs, _Els} = El}, - StateName, StateData) -> + El}, + StateName, StateData) when ?IS_MESSAGE(El) -> NewStateData = - case xml:get_attr_s("type", Attrs) of - "chat" -> - Body = xml:get_path_s(El, [{elem, "body"}, cdata]), + case exmpp_message:get_type(El) of + 'chat' -> + Body = binary_to_list(exmpp_message:get_body(El)), case Body of "/quote " ++ Rest -> ?SEND(Rest ++ "\r\n"); @@ -451,7 +448,7 @@ handle_info({route_nick, Nick, end, Strings)), ?SEND(Res) end; - "error" -> + 'error' -> stop; _ -> StateData @@ -585,17 +582,17 @@ terminate(_Reason, _StateName, StateData) -> mod_irc:closed_connection(StateData#state.host, StateData#state.user, StateData#state.server), - bounce_messages("Server Connect Failed"), + bounce_messages(<<"Server Connect Failed">>), lists:foreach( fun(Chan) -> ejabberd_router:route( - jlib:make_jid( + exmpp_jid:make_jid( lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, StateData#state.nick), StateData#state.user, - {xmlelement, "presence", [{"type", "error"}], - [{xmlelement, "error", [{"code", "502"}], - [{xmlcdata, "Server Connect Failed"}]}]}) + #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', attrs = [#xmlattr{name = 'type', value = "error"}], children = + [#xmlel{ns = ?NS_JABBER_CLIENT, name = 'error', attrs = [#xmlattr{name = 'code', value = "502"}], children = + [#xmlcdata{cdata = <<"Server Connect Failed">>}]}]}) end, dict:fetch_keys(StateData#state.channels)), case StateData#state.socket of undefined -> @@ -627,15 +624,16 @@ send_text(#state{socket = Socket, encoding = Encoding}, Text) -> bounce_messages(Reason) -> receive {send_element, El} -> - {xmlelement, _Name, Attrs, _SubTags} = El, - case xml:get_attr_s("type", Attrs) of + case exmpp_stanza:get_type(El) of "error" -> ok; _ -> - Err = jlib:make_error_reply(El, - "502", Reason), - From = jlib:string_to_jid(xml:get_attr_s("from", Attrs)), - To = jlib:string_to_jid(xml:get_attr_s("to", Attrs)), + Error = #xmlel{ns = ?NS_JABBER_CLIENT, name = 'error', + attrs = [#xmlattr{name = 'code', value = "502"}], + children = [#xmlcdata{cdata = Reason}]}, + Err = exmpp_stanza:reply_with_error(El, Error), + From = exmpp_jid:list_to_jid(exmpp_stanza:get_sender(El)), + To = exmpp_jid:list_to_jid(exmpp_stanza:get_recipient(El)), ejabberd_router:route(To, From, Err) end, bounce_messages(Reason) @@ -688,15 +686,14 @@ process_channel_list_user(StateData, Chan, User) -> _ -> {User1, "member", "participant"} end, ejabberd_router:route( - jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), + exmpp_jid:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, User2), StateData#state.user, - {xmlelement, "presence", [], - [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], - [{xmlelement, "item", - [{"affiliation", Affiliation}, - {"role", Role}], - []}]}]}), + #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', children = + [#xmlel{ns = ?NS_MUC_USER, name = 'x', children = + [#xmlel{ns = ?NS_MUC_USER, name = 'item', attrs = + [#xmlattr{name = 'affiliation', value = Affiliation}, + #xmlattr{name = 'role', value = Role}]}]}]}), case catch dict:update(Chan, fun(Ps) -> ?SETS:add_element(User2, Ps) @@ -712,14 +709,11 @@ process_channel_topic(StateData, Chan, String) -> {ok, Msg, _} = regexp:sub(String, ".*332[^:]*:", ""), Msg1 = filter_message(Msg), ejabberd_router:route( - jlib:make_jid( + exmpp_jid:make_jid( lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, ""), StateData#state.user, - {xmlelement, "message", [{"type", "groupchat"}], - [{xmlelement, "subject", [], [{xmlcdata, Msg1}]}, - {xmlelement, "body", [], [{xmlcdata, "Topic for #" ++ Chan ++ ": " ++ Msg1}]} - ]}). + exmpp_message:groupchat(Msg1, "Topic for #" ++ Chan ++ ": " ++ Msg1)). process_channel_topic_who(StateData, Chan, String) -> Words = string:tokens(String, " "), @@ -740,55 +734,47 @@ process_channel_topic_who(StateData, Chan, String) -> Msg2 = filter_message(Msg1), ejabberd_router:route( - jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), + exmpp_jid:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, ""), StateData#state.user, - {xmlelement, "message", [{"type", "groupchat"}], - [{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}). + exmpp_message:groupchat(Msg2)). process_endofwhois(StateData, _String, Nick) -> ejabberd_router:route( - jlib:make_jid(lists:concat([Nick, "!", StateData#state.server]), + exmpp_jid:make_jid(lists:concat([Nick, "!", StateData#state.server]), StateData#state.host, ""), StateData#state.user, - {xmlelement, "message", [{"type", "chat"}], - [{xmlelement, "body", [], [{xmlcdata, "End of WHOIS"}]}]}). + exmpp_message:chat("End of WHOIS")). process_whois311(StateData, String, Nick, Ident, Irchost) -> {ok, Fullname, _} = regexp:sub(String, ".*311[^:]*:", ""), ejabberd_router:route( - jlib:make_jid(lists:concat([Nick, "!", StateData#state.server]), + exmpp_jid:make_jid(lists:concat([Nick, "!", StateData#state.server]), StateData#state.host, ""), StateData#state.user, - {xmlelement, "message", [{"type", "chat"}], - [{xmlelement, "body", [], - [{xmlcdata, lists:concat( + exmpp_message:chat(lists:concat( ["WHOIS: ", Nick, " is ", - Ident, "@" , Irchost, " : " , Fullname])}]}]}). + Ident, "@" , Irchost, " : " , Fullname]))). process_whois312(StateData, String, Nick, Ircserver) -> {ok, Ircserverdesc, _} = regexp:sub(String, ".*312[^:]*:", ""), ejabberd_router:route( - jlib:make_jid(lists:concat([Nick, "!", StateData#state.server]), + exmpp_jid:make_jid(lists:concat([Nick, "!", StateData#state.server]), StateData#state.host, ""), StateData#state.user, - {xmlelement, "message", [{"type", "chat"}], - [{xmlelement, "body", [], - [{xmlcdata, lists:concat(["WHOIS: ", Nick, " use ", - Ircserver, " : ", Ircserverdesc])}]}]}). + exmpp_message:chat(lists:concat(["WHOIS: ", Nick, " use ", + Ircserver, " : ", Ircserverdesc]))). process_whois319(StateData, String, Nick) -> {ok, Chanlist, _} = regexp:sub(String, ".*319[^:]*:", ""), ejabberd_router:route( - jlib:make_jid(lists:concat([Nick, "!", StateData#state.server]), + exmpp_jid:make_jid(lists:concat([Nick, "!", StateData#state.server]), StateData#state.host, ""), StateData#state.user, - {xmlelement, "message", [{"type", "chat"}], - [{xmlelement, "body", [], - [{xmlcdata, lists:concat(["WHOIS: ", Nick, " is on ", - Chanlist])}]}]}). + exmpp_message:chat(lists:concat(["WHOIS: ", Nick, " is on ", + Chanlist]))). @@ -803,11 +789,10 @@ process_chanprivmsg(StateData, Chan, From, String) -> end, Msg2 = filter_message(Msg1), ejabberd_router:route( - jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), + exmpp_jid:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, FromUser), StateData#state.user, - {xmlelement, "message", [{"type", "groupchat"}], - [{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}). + exmpp_message:groupchat(Msg2)). @@ -822,11 +807,10 @@ process_channotice(StateData, Chan, From, String) -> end, Msg2 = filter_message(Msg1), ejabberd_router:route( - jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), + exmpp_jid:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, FromUser), StateData#state.user, - {xmlelement, "message", [{"type", "groupchat"}], - [{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}). + exmpp_message:groupchat(Msg2)). @@ -842,11 +826,10 @@ process_privmsg(StateData, _Nick, From, String) -> end, Msg2 = filter_message(Msg1), ejabberd_router:route( - jlib:make_jid(lists:concat([FromUser, "!", StateData#state.server]), - StateData#state.host, ""), + exmpp_jid:make_jid(lists:concat([FromUser, "!", StateData#state.server]), + StateData#state.host, undefined), StateData#state.user, - {xmlelement, "message", [{"type", "chat"}], - [{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}). + exmpp_message:chat(Msg2)). process_notice(StateData, _Nick, From, String) -> @@ -860,11 +843,10 @@ process_notice(StateData, _Nick, From, String) -> end, Msg2 = filter_message(Msg1), ejabberd_router:route( - jlib:make_jid(lists:concat([FromUser, "!", StateData#state.server]), - StateData#state.host, ""), + exmpp_jid:make_jid(lists:concat([FromUser, "!", StateData#state.server]), + StateData#state.host, undefined), StateData#state.user, - {xmlelement, "message", [{"type", "chat"}], - [{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}). + exmpp_message:chat(Msg2)). process_version(StateData, _Nick, From) -> @@ -889,7 +871,7 @@ process_userinfo(StateData, _Nick, From) -> "xmpp:~s" "\001\r\n", [FromUser, - jlib:jid_to_string(StateData#state.user)])). + exmpp_jid:jid_to_list(StateData#state.user)])). process_topic(StateData, Chan, From, String) -> @@ -897,31 +879,27 @@ process_topic(StateData, Chan, From, String) -> {ok, Msg, _} = regexp:sub(String, ".*TOPIC[^:]*:", ""), Msg1 = filter_message(Msg), ejabberd_router:route( - jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), + exmpp_jid:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, FromUser), StateData#state.user, - {xmlelement, "message", [{"type", "groupchat"}], - [{xmlelement, "subject", [], [{xmlcdata, Msg1}]}, - {xmlelement, "body", [], - [{xmlcdata, "/me has changed the subject to: " ++ - Msg1}]}]}). + exmpp_message:groupchat(Msg1, + "/me has changed the subject to: " ++ Msg1)). process_part(StateData, Chan, From, String) -> [FromUser | FromIdent] = string:tokens(From, "!"), {ok, Msg, _} = regexp:sub(String, ".*PART[^:]*:", ""), Msg1 = filter_message(Msg), ejabberd_router:route( - jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), + exmpp_jid:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, FromUser), StateData#state.user, - {xmlelement, "presence", [{"type", "unavailable"}], - [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], - [{xmlelement, "item", - [{"affiliation", "member"}, - {"role", "none"}], - []}]}, - {xmlelement, "status", [], - [{xmlcdata, Msg1 ++ " (" ++ FromIdent ++ ")"}]}] + #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', attrs = [#xmlattr{name = 'type', value = "unavailable"}], children = + [#xmlel{ns = ?NS_MUC_USER, name = 'x', children = + [#xmlel{ns = ?NS_MUC_USER, name = 'item', attrs = + [#xmlattr{name = 'affiliation', value = "member"}, + #xmlattr{name = 'role', value = "none"}]}]}, + #xmlel{ns = ?NS_MUC_USER, name = 'status', children = + [#xmlcdata{cdata = list_to_binary(Msg1 ++ " (" ++ FromIdent ++ ")")}]}] }), case catch dict:update(Chan, fun(Ps) -> @@ -945,18 +923,17 @@ process_quit(StateData, From, String) -> case ?SETS:is_member(FromUser, Ps) of true -> ejabberd_router:route( - jlib:make_jid( + exmpp_jid:make_jid( lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, FromUser), StateData#state.user, - {xmlelement, "presence", [{"type", "unavailable"}], - [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], - [{xmlelement, "item", - [{"affiliation", "member"}, - {"role", "none"}], - []}]}, - {xmlelement, "status", [], - [{xmlcdata, Msg1 ++ " (" ++ FromIdent ++ ")"}]} + #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', attrs = [#xmlattr{name = 'type', value = "unavailable"}], children = + [#xmlel{ns = ?NS_MUC_USER, name = 'x', children = + [#xmlel{ns = ?NS_MUC_USER, name = 'item', attrs = + [#xmlattr{name = 'affiliation', value = "member"}, + #xmlattr{name = 'role', value = "none"}]}]}, + #xmlel{ns = ?NS_MUC_USER, name = 'status', children = + [#xmlcdata{cdata = list_to_binary(Msg1 ++ " (" ++ FromIdent ++ ")")}]} ]}), remove_element(FromUser, Ps); _ -> @@ -970,17 +947,16 @@ process_join(StateData, Channel, From, _String) -> [FromUser | FromIdent] = string:tokens(From, "!"), Chan = lists:subtract(Channel, ":#"), ejabberd_router:route( - jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), + exmpp_jid:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, FromUser), StateData#state.user, - {xmlelement, "presence", [], - [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], - [{xmlelement, "item", - [{"affiliation", "member"}, - {"role", "participant"}], - []}]}, - {xmlelement, "status", [], - [{xmlcdata, FromIdent}]}]}), + #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', children = + [#xmlel{ns = ?NS_MUC_USER, name = 'x', children = + [#xmlel{ns = ?NS_MUC_USER, name = 'item', attrs = + [#xmlattr{name = 'affiliation', value = "member"}, + #xmlattr{name = 'role', value = "participant"}]}]}, + #xmlel{ns = ?NS_MUC_USER, name = 'status', children = + [#xmlcdata{cdata = list_to_binary(FromIdent)}]}]}), case catch dict:update(Chan, fun(Ps) -> @@ -997,36 +973,33 @@ process_join(StateData, Channel, From, _String) -> process_mode_o(StateData, Chan, _From, Nick, Affiliation, Role) -> %Msg = lists:last(string:tokens(String, ":")), ejabberd_router:route( - jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), + exmpp_jid:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, Nick), StateData#state.user, - {xmlelement, "presence", [], - [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], - [{xmlelement, "item", - [{"affiliation", Affiliation}, - {"role", Role}], - []}]}]}). + #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', children = + [#xmlel{ns = ?NS_MUC_USER, name = 'x', children = + [#xmlel{ns = ?NS_MUC_USER, name = 'item', attrs = + [#xmlattr{name = 'affiliation', value = Affiliation}, + #xmlattr{name = 'role', value = Role}]}]}]}). process_kick(StateData, Chan, From, Nick, String) -> Msg = lists:last(string:tokens(String, ":")), Msg2 = Nick ++ " kicked by " ++ From ++ " (" ++ filter_message(Msg) ++ ")", ejabberd_router:route( - jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), - StateData#state.host, ""), + exmpp_jid:make_jid(lists:concat([Chan, "%", StateData#state.server]), + StateData#state.host, undefined), StateData#state.user, - {xmlelement, "message", [{"type", "groupchat"}], - [{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}), + exmpp_message:groupchat(Msg2)), ejabberd_router:route( - jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), + exmpp_jid:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, Nick), StateData#state.user, - {xmlelement, "presence", [{"type", "unavailable"}], - [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], - [{xmlelement, "item", - [{"affiliation", "none"}, - {"role", "none"}], - []}, - {xmlelement, "status", [{"code", "307"}], []} + #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', attrs = [#xmlattr{name = 'type', value = "unavailable"}], children = + [#xmlel{ns = ?NS_MUC_USER, name = 'x', children = + [#xmlel{ns = ?NS_MUC_USER, name = 'item', attrs = + [#xmlattr{name = 'affiliation', value = "none"}, + #xmlattr{name = 'role', value = "none"}]}, + #xmlel{ns = ?NS_MUC_USER, name = 'status', attrs = [#xmlattr{name = 'code', value = "307"}]} ]}]}). process_nick(StateData, From, NewNick) -> @@ -1038,30 +1011,28 @@ process_nick(StateData, From, NewNick) -> case ?SETS:is_member(FromUser, Ps) of true -> ejabberd_router:route( - jlib:make_jid( + exmpp_jid:make_jid( lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, FromUser), StateData#state.user, - {xmlelement, "presence", [{"type", "unavailable"}], - [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], - [{xmlelement, "item", - [{"affiliation", "member"}, - {"role", "participant"}, - {"nick", Nick}], - []}, - {xmlelement, "status", [{"code", "303"}], []} + #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', attrs = [#xmlattr{name = 'type', value = "unavailable"}], children = + [#xmlel{ns = ?NS_MUC_USER, name = 'x', children = + [#xmlel{ns = ?NS_MUC_USER, name = 'item', attrs = + [#xmlattr{name = 'affiliation', value = "member"}, + #xmlattr{name = 'role', value = "participant"}, + #xmlattr{name = 'nick', value = Nick}]}, + #xmlel{ns = ?NS_MUC_USER, name = 'status', attrs = [#xmlattr{name = 'code', value = "303"}]} ]}]}), ejabberd_router:route( - jlib:make_jid( + exmpp_jid:make_jid( lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, Nick), StateData#state.user, - {xmlelement, "presence", [], - [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], - [{xmlelement, "item", - [{"affiliation", "member"}, - {"role", "participant"}], - []} + #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', children = + [#xmlel{ns = ?NS_MUC_USER, name = 'x', children = + [#xmlel{ns = ?NS_MUC_USER, name = 'item', attrs = + [#xmlattr{name = 'affiliation', value = "member"}, + #xmlattr{name = 'role', value = "participant"}]} ]}]}), ?SETS:add_element(Nick, remove_element(FromUser, Ps)); @@ -1076,13 +1047,13 @@ process_error(StateData, String) -> lists:foreach( fun(Chan) -> ejabberd_router:route( - jlib:make_jid( + exmpp_jid:make_jid( lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, StateData#state.nick), StateData#state.user, - {xmlelement, "presence", [{"type", "error"}], - [{xmlelement, "error", [{"code", "502"}], - [{xmlcdata, String}]}]}) + #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', attrs = [#xmlattr{name = 'type', value = "error"}], children = + [#xmlel{ns = ?NS_JABBER_CLIENT, name = 'error', attrs = [#xmlattr{name = 'code', value = "502"}], children = + [#xmlcdata{cdata = list_to_binary(String)}]}]}) end, dict:fetch_keys(StateData#state.channels)). @@ -1099,7 +1070,7 @@ remove_element(E, Set) -> iq_admin(StateData, Channel, From, To, - #iq{type = Type, xmlns = XMLNS, sub_el = SubEl} = IQ) -> + #iq{type = Type, ns = XMLNS, payload = SubEl} = IQ_Rec) -> case catch process_iq_admin(StateData, Channel, Type, SubEl) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); @@ -1108,17 +1079,14 @@ iq_admin(StateData, Channel, From, To, Res /= ignore -> ResIQ = case Res of {result, ResEls} -> - IQ#iq{type = result, - sub_el = [{xmlelement, "query", - [{"xmlns", XMLNS}], - ResEls - }]}; + Result = #xmlel{ns = XMLNS, name = 'query', + children = ResEls}, + exmpp_iq:result(IQ_Rec, Result); {error, Error} -> - IQ#iq{type = error, - sub_el = [SubEl, Error]} + exmpp_iq:error(IQ_Rec, Error) end, ejabberd_router:route(To, From, - jlib:iq_to_xml(ResIQ)); + exmpp_iq:iq_to_xmlel(ResIQ)); true -> ok end @@ -1126,23 +1094,23 @@ iq_admin(StateData, Channel, From, To, process_iq_admin(StateData, Channel, set, SubEl) -> - case xml:get_subtag(SubEl, "item") of + case exmpp_xml:get_element(SubEl, 'item') of false -> - {error, ?ERR_BAD_REQUEST}; + {error, 'bad-request'}; ItemEl -> - Nick = xml:get_tag_attr_s("nick", ItemEl), - Affiliation = xml:get_tag_attr_s("affiliation", ItemEl), - Role = xml:get_tag_attr_s("role", ItemEl), - Reason = xml:get_path_s(ItemEl, [{elem, "reason"}, cdata]), + Nick = exmpp_xml:get_attribute(ItemEl, 'nick', ""), + Affiliation = exmpp_xml:get_attribute(ItemEl, 'affiliation', ""), + Role = exmpp_xml:get_attribute(ItemEl, 'role', ""), + Reason = exmpp_xml:get_path(ItemEl, [{element, 'reason'}, cdata_as_list]), process_admin(StateData, Channel, Nick, Affiliation, Role, Reason) end; process_iq_admin(_StateData, _Channel, get, _SubEl) -> - {error, ?ERR_FEATURE_NOT_IMPLEMENTED}. + {error, 'feature-not-implemented'}. process_admin(_StateData, _Channel, "", _Affiliation, _Role, _Reason) -> - {error, ?ERR_FEATURE_NOT_IMPLEMENTED}; + {error, 'feature-not-implemented'}; process_admin(StateData, Channel, Nick, _Affiliation, "none", Reason) -> case Reason of @@ -1160,7 +1128,7 @@ process_admin(StateData, Channel, Nick, _Affiliation, "none", Reason) -> process_admin(_StateData, _Channel, _Nick, _Affiliation, _Role, _Reason) -> - {error, ?ERR_FEATURE_NOT_IMPLEMENTED}. + {error, 'feature-not-implemented'}.