aboutsummaryrefslogtreecommitdiff
path: root/src/mod_adhoc.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mod_adhoc.erl')
-rw-r--r--src/mod_adhoc.erl205
1 files changed, 96 insertions, 109 deletions
diff --git a/src/mod_adhoc.erl b/src/mod_adhoc.erl
index e12e0de1e..edba1cebe 100644
--- a/src/mod_adhoc.erl
+++ b/src/mod_adhoc.erl
@@ -5,7 +5,7 @@
%%% Created : 15 Nov 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -31,27 +31,22 @@
-behaviour(gen_mod).
--export([start/2, stop/1, process_local_iq/3,
- process_sm_iq/3, get_local_commands/5,
+-export([start/2, stop/1, reload/3, process_local_iq/1,
+ process_sm_iq/1, get_local_commands/5,
get_local_identity/5, get_local_features/5,
get_sm_commands/5, get_sm_identity/5, get_sm_features/5,
- ping_item/4, ping_command/4, mod_opt_type/1, depends/2]).
+ ping_item/4, ping_command/4, mod_opt_type/1, depends/2,
+ mod_options/1]).
--include("ejabberd.hrl").
-include("logger.hrl").
+-include("xmpp.hrl").
+-include("translate.hrl").
--include("jlib.hrl").
-
--include("adhoc.hrl").
-
-start(Host, Opts) ->
- IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
- one_queue),
+start(Host, _Opts) ->
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
- ?NS_COMMANDS, ?MODULE, process_local_iq,
- IQDisc),
+ ?NS_COMMANDS, ?MODULE, process_local_iq),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
- ?NS_COMMANDS, ?MODULE, process_sm_iq, IQDisc),
+ ?NS_COMMANDS, ?MODULE, process_sm_iq),
ejabberd_hooks:add(disco_local_identity, Host, ?MODULE,
get_local_identity, 99),
ejabberd_hooks:add(disco_local_features, Host, ?MODULE,
@@ -91,15 +86,15 @@ stop(Host) ->
gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
?NS_COMMANDS).
-%-------------------------------------------------------------------------
+reload(_Host, _NewOpts, _OldOpts) ->
+ ok.
+%-------------------------------------------------------------------------
+-spec get_local_commands(mod_disco:items_acc(), jid(), jid(), binary(), binary()) -> mod_disco:items_acc().
get_local_commands(Acc, _From,
#jid{server = Server, lserver = LServer} = _To, <<"">>,
Lang) ->
- Display = gen_mod:get_module_opt(LServer, ?MODULE,
- report_commands_node,
- fun(B) when is_boolean(B) -> B end,
- false),
+ Display = mod_adhoc_opt:report_commands_node(LServer),
case Display of
false -> Acc;
_ ->
@@ -107,12 +102,9 @@ get_local_commands(Acc, _From,
{result, I} -> I;
_ -> []
end,
- Nodes = [#xmlel{name = <<"item">>,
- attrs =
- [{<<"jid">>, Server}, {<<"node">>, ?NS_COMMANDS},
- {<<"name">>,
- translate:translate(Lang, <<"Commands">>)}],
- children = []}],
+ Nodes = [#disco_item{jid = jid:make(Server),
+ node = ?NS_COMMANDS,
+ name = translate:translate(Lang, ?T("Commands"))}],
{result, Items ++ Nodes}
end;
get_local_commands(_Acc, From,
@@ -126,13 +118,10 @@ get_local_commands(Acc, _From, _To, _Node, _Lang) ->
Acc.
%-------------------------------------------------------------------------
-
+-spec get_sm_commands(mod_disco:items_acc(), jid(), jid(), binary(), binary()) -> mod_disco:items_acc().
get_sm_commands(Acc, _From,
#jid{lserver = LServer} = To, <<"">>, Lang) ->
- Display = gen_mod:get_module_opt(LServer, ?MODULE,
- report_commands_node,
- fun(B) when is_boolean(B) -> B end,
- false),
+ Display = mod_adhoc_opt:report_commands_node(LServer),
case Display of
false -> Acc;
_ ->
@@ -140,13 +129,9 @@ get_sm_commands(Acc, _From,
{result, I} -> I;
_ -> []
end,
- Nodes = [#xmlel{name = <<"item">>,
- attrs =
- [{<<"jid">>, jid:to_string(To)},
- {<<"node">>, ?NS_COMMANDS},
- {<<"name">>,
- translate:translate(Lang, <<"Commands">>)}],
- children = []}],
+ Nodes = [#disco_item{jid = To,
+ node = ?NS_COMMANDS,
+ name = translate:translate(Lang, ?T("Commands"))}],
{result, Items ++ Nodes}
end;
get_sm_commands(_Acc, From,
@@ -156,45 +141,34 @@ get_sm_commands(_Acc, From,
get_sm_commands(Acc, _From, _To, _Node, _Lang) -> Acc.
%-------------------------------------------------------------------------
-
+-spec get_local_identity([identity()], jid(), jid(), binary(), binary()) -> [identity()].
%% On disco info request to the ad-hoc node, return automation/command-list.
get_local_identity(Acc, _From, _To, ?NS_COMMANDS,
Lang) ->
- [#xmlel{name = <<"identity">>,
- attrs =
- [{<<"category">>, <<"automation">>},
- {<<"type">>, <<"command-list">>},
- {<<"name">>,
- translate:translate(Lang, <<"Commands">>)}],
- children = []}
+ [#identity{category = <<"automation">>,
+ type = <<"command-list">>,
+ name = translate:translate(Lang, ?T("Commands"))}
| Acc];
get_local_identity(Acc, _From, _To, <<"ping">>, Lang) ->
- [#xmlel{name = <<"identity">>,
- attrs =
- [{<<"category">>, <<"automation">>},
- {<<"type">>, <<"command-node">>},
- {<<"name">>, translate:translate(Lang, <<"Ping">>)}],
- children = []}
+ [#identity{category = <<"automation">>,
+ type = <<"command-node">>,
+ name = translate:translate(Lang, ?T("Ping"))}
| Acc];
get_local_identity(Acc, _From, _To, _Node, _Lang) ->
Acc.
%-------------------------------------------------------------------------
-
+-spec get_sm_identity([identity()], jid(), jid(), binary(), binary()) -> [identity()].
%% On disco info request to the ad-hoc node, return automation/command-list.
get_sm_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) ->
- [#xmlel{name = <<"identity">>,
- attrs =
- [{<<"category">>, <<"automation">>},
- {<<"type">>, <<"command-list">>},
- {<<"name">>,
- translate:translate(Lang, <<"Commands">>)}],
- children = []}
+ [#identity{category = <<"automation">>,
+ type = <<"command-list">>,
+ name = translate:translate(Lang, ?T("Commands"))}
| Acc];
get_sm_identity(Acc, _From, _To, _Node, _Lang) -> Acc.
%-------------------------------------------------------------------------
-
+-spec get_local_features(mod_disco:features_acc(), jid(), jid(), binary(), binary()) -> mod_disco:features_acc().
get_local_features(Acc, _From, _To, <<"">>, _Lang) ->
Feats = case Acc of
{result, I} -> I;
@@ -211,7 +185,7 @@ get_local_features(Acc, _From, _To, _Node, _Lang) ->
Acc.
%-------------------------------------------------------------------------
-
+-spec get_sm_features(mod_disco:features_acc(), jid(), jid(), binary(), binary()) -> mod_disco:features_acc().
get_sm_features(Acc, _From, _To, <<"">>, _Lang) ->
Feats = case Acc of
{result, I} -> I;
@@ -224,70 +198,83 @@ get_sm_features(_Acc, _From, _To, ?NS_COMMANDS,
get_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc.
%-------------------------------------------------------------------------
+-spec process_local_iq(iq()) -> iq() | ignore.
+process_local_iq(IQ) ->
+ process_adhoc_request(IQ, local).
-process_local_iq(From, To, IQ) ->
- process_adhoc_request(From, To, IQ,
- adhoc_local_commands).
-
-process_sm_iq(From, To, IQ) ->
- process_adhoc_request(From, To, IQ, adhoc_sm_commands).
+-spec process_sm_iq(iq()) -> iq() | ignore.
+process_sm_iq(IQ) ->
+ process_adhoc_request(IQ, sm).
-process_adhoc_request(From, To,
- #iq{sub_el = SubEl, lang = Lang} = IQ, Hook) ->
- ?DEBUG("About to parse ~p...", [IQ]),
- case adhoc:parse_request(IQ) of
- {error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]};
- #adhoc_request{} = AdhocRequest ->
- Host = To#jid.lserver,
- case ejabberd_hooks:run_fold(Hook, Host, empty,
- [From, To, AdhocRequest])
- of
- ignore -> ignore;
- empty ->
- Txt = <<"No hook has processed this command">>,
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)]};
- {error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]};
- Command -> IQ#iq{type = result, sub_el = [Command]}
- end
- end.
+-spec process_adhoc_request(iq(), sm | local) -> iq() | ignore.
+process_adhoc_request(#iq{from = From, to = To,
+ type = set, lang = Lang,
+ sub_els = [#adhoc_command{} = SubEl]} = IQ, Type) ->
+ Host = To#jid.lserver,
+ Res = case Type of
+ local ->
+ ejabberd_hooks:run_fold(adhoc_local_commands, Host, empty,
+ [From, To, fix_lang(Lang, SubEl)]);
+ sm ->
+ ejabberd_hooks:run_fold(adhoc_sm_commands, Host, empty,
+ [From, To, fix_lang(Lang, SubEl)])
+ end,
+ case Res of
+ ignore ->
+ ignore;
+ empty ->
+ Txt = ?T("No hook has processed this command"),
+ xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang));
+ {error, Error} ->
+ xmpp:make_error(IQ, Error);
+ Command ->
+ xmpp:make_iq_result(IQ, Command)
+ end;
+process_adhoc_request(#iq{} = IQ, _Hooks) ->
+ xmpp:make_error(IQ, xmpp:err_bad_request()).
+-spec ping_item(mod_disco:items_acc(), jid(), jid(), binary()) -> {result, [disco_item()]}.
ping_item(Acc, _From, #jid{server = Server} = _To,
Lang) ->
Items = case Acc of
{result, I} -> I;
_ -> []
end,
- Nodes = [#xmlel{name = <<"item">>,
- attrs =
- [{<<"jid">>, Server}, {<<"node">>, <<"ping">>},
- {<<"name">>, translate:translate(Lang, <<"Ping">>)}],
- children = []}],
+ Nodes = [#disco_item{jid = jid:make(Server),
+ node = <<"ping">>,
+ name = translate:translate(Lang, ?T("Ping"))}],
{result, Items ++ Nodes}.
+-spec ping_command(adhoc_command(), jid(), jid(), adhoc_command()) ->
+ adhoc_command() | {error, stanza_error()}.
ping_command(_Acc, _From, _To,
- #adhoc_request{lang = Lang, node = <<"ping">>,
- sessionid = _Sessionid, action = Action} =
- Request) ->
- if Action == <<"">>; Action == <<"execute">> ->
- adhoc:produce_response(Request,
- #adhoc_response{status = completed,
- notes =
- [{<<"info">>,
- translate:translate(Lang,
- <<"Pong">>)}]});
+ #adhoc_command{lang = Lang, node = <<"ping">>,
+ action = Action} = Request) ->
+ if Action == execute ->
+ xmpp_util:make_adhoc_response(
+ Request,
+ #adhoc_command{
+ status = completed,
+ notes = [#adhoc_note{
+ type = info,
+ data = translate:translate(Lang, ?T("Pong"))}]});
true ->
- Txt = <<"Incorrect value of 'action' attribute">>,
- {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
+ Txt = ?T("Incorrect value of 'action' attribute"),
+ {error, xmpp:err_bad_request(Txt, Lang)}
end;
ping_command(Acc, _From, _To, _Request) -> Acc.
+-spec fix_lang(binary(), adhoc_command()) -> adhoc_command().
+fix_lang(Lang, #adhoc_command{lang = <<>>} = Cmd) ->
+ Cmd#adhoc_command{lang = Lang};
+fix_lang(_, Cmd) ->
+ Cmd.
+
depends(_Host, _Opts) ->
[].
-mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1;
mod_opt_type(report_commands_node) ->
- fun (B) when is_boolean(B) -> B end;
-mod_opt_type(_) -> [iqdisc, report_commands_node].
+ econf:bool().
+
+mod_options(_Host) ->
+ [{report_commands_node, false}].