mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
Convert to exmpp.
PR: EJABP-1 SVN Revision: 1663
This commit is contained in:
parent
50b1e4c36f
commit
0313adaec6
@ -1,3 +1,8 @@
|
||||
2008-10-20 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||
|
||||
* src/mod_irc/mod_irc.erl, src/mod_irc/mod_irc_connection.erl: Convert
|
||||
to exmpp.
|
||||
|
||||
2008-10-13 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||
|
||||
* src/web/ejabberd_http.erl, src/web/ejabberd_http_poll.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}
|
||||
|
@ -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'}.
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user