diff options
author | Alexey Shchepin <alexey@process-one.net> | 2006-01-19 05:17:31 +0300 |
---|---|---|
committer | Alexey Shchepin <alexey@process-one.net> | 2006-01-19 05:17:31 +0300 |
commit | 568909d5bb454fab2023e7ab1a7cf62eff8dcd39 (patch) | |
tree | 562acb2d39d04393e19bda367791a2d8f04e6289 /src/mod_adhoc.erl | |
parent | c7bafe005698625a092e0359414b09ea066a25c0 (diff) |
* src/aclocal.m4: Updated for zlib support
* src/configure.ac: Likewise
* src/mod_muc/mod_muc_room.erl: Weakened presence filtering, added
warning in non-anonymous rooms, room destroying updated to latest
JEP-0045, added a number of occupants and room name in room's
disco#info reply, miscellaneous internal changes (thanks to Sergei
Golovan)
* src/mod_muc/mod_muc.erl: Better support for nick unregistration
(thanks to Sergei Golovan)
* src/ejabberd_zlib/ejabberd_zlib.erl: Zlib support (thanks to
Sergei Golovan)
* src/ejabberd_zlib/ejabberd_zlib_drv.c: Likewise
* src/ejabberd_zlib/Makefile.in: Likewise
* src/ejabberd_c2s.erl: Stream compression support (JEP-0138)
* src/ejabberd_receiver.erl: Likewise
* src/mod_disco.erl: Don't split node name before calling hooks
(thanks to Sergei Golovan)
* src/mod_configure.erl: Support for configuration using ad-hoc
commands (thanks to Sergei Golovan)
* src/mod_announce.erl: Support for sending announce messages
using ad-hoc commands (thanks to Sergei Golovan)
* src/mod_adhoc.erl: Ad-hoc support (JEP-0050) (thanks to Magnus
Henoch)
* src/adhoc.erl: Likewise
* src/adhoc.hrl: Likewise
* src/jlib.hrl: Updated (thanks to Sergei Golovan)
* src/gen_mod.erl: Added function is_loaded/2 (thanks to Sergei
Golovan)
* src/ejabberd_service.erl: Changed error message on handshake
error (thanks to Sergei Golovan)
* src/ejabberd.cfg.example: Updated (thanks to Sergei Golovan)
SVN Revision: 486
Diffstat (limited to 'src/mod_adhoc.erl')
-rw-r--r-- | src/mod_adhoc.erl | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/src/mod_adhoc.erl b/src/mod_adhoc.erl new file mode 100644 index 000000000..4288524ab --- /dev/null +++ b/src/mod_adhoc.erl @@ -0,0 +1,250 @@ +%%%---------------------------------------------------------------------- +%%% File : mod_adhoc.erl +%%% Author : Magnus Henoch <henoch@dtek.chalmers.se> +%%% Purpose : Handle incoming ad-doc requests (JEP-0050) +%%% Created : 15 Nov 2005 by Magnus Henoch <henoch@dtek.chalmers.se> +%%% Id : $Id$ +%%%---------------------------------------------------------------------- + +-module(mod_adhoc). +-author('henoch@dtek.chalmers.se'). +-vsn('$Revision$ '). + +-behaviour(gen_mod). + +-export([start/2, + stop/1, + process_local_iq/3, + process_sm_iq/3, + 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]). + +-include("ejabberd.hrl"). +-include("jlib.hrl"). +-include("adhoc.hrl"). + +start(Host, Opts) -> + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), + + gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_COMMANDS, + ?MODULE, process_local_iq, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_COMMANDS, + ?MODULE, process_sm_iq, IQDisc), + + ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, get_local_identity, 99), + ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_local_features, 99), + ejabberd_hooks:add(disco_local_items, Host, ?MODULE, get_local_commands, 99), + ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, get_sm_identity, 99), + ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 99), + ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_sm_commands, 99), + ejabberd_hooks:add(adhoc_local_items, Host, ?MODULE, ping_item, 100), + ejabberd_hooks:add(adhoc_local_commands, Host, ?MODULE, ping_command, 100). + +stop(Host) -> + ejabberd_hooks:delete(adhoc_local_commands, Host, ?MODULE, ping_command, 100), + ejabberd_hooks:delete(adhoc_local_items, Host, ?MODULE, ping_item, 100), + ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, get_sm_commands, 99), + ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 99), + ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, get_sm_identity, 99), + ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_commands, 99), + ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 99), + ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 99), + + gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_COMMANDS), + gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_COMMANDS). + +%------------------------------------------------------------------------- + +get_local_commands(Acc, _From, #jid{server = Server, lserver = LServer} = _To, "", Lang) -> + Display = gen_mod:get_module_opt(LServer, ?MODULE, report_commands_node, false), + case Display of + false -> + Acc; + _ -> + Items = case Acc of + {result, I} -> I; + _ -> [] + end, + Nodes = [{xmlelement, + "item", + [{"jid", Server}, + {"node", ?NS_COMMANDS}, + {"name", translate:translate(Lang, "Commands")}], + []}], + {result, Items ++ Nodes} + end; + +get_local_commands(_Acc, From, #jid{lserver = LServer} = To, ?NS_COMMANDS, Lang) -> + ejabberd_hooks:run_fold(adhoc_local_items, LServer, {result, []}, [From, To, Lang]); + +get_local_commands(_Acc, _From, _To, "ping", _Lang) -> + {result, []}; + +get_local_commands(Acc, _From, _To, _Node, _Lang) -> + Acc. + +%------------------------------------------------------------------------- + +get_sm_commands(Acc, _From, #jid{lserver = LServer} = To, "", Lang) -> + Display = gen_mod:get_module_opt(LServer, ?MODULE, report_commands_node, false), + case Display of + false -> + Acc; + _ -> + Items = case Acc of + {result, I} -> I; + _ -> [] + end, + Nodes = [{xmlelement, + "item", + [{"jid", jlib:jid_to_string(To)}, + {"node", ?NS_COMMANDS}, + {"name", translate:translate(Lang, "Commands")}], + []}], + {result, Items ++ Nodes} + end; + +get_sm_commands(_Acc, From, #jid{lserver = LServer} = To, ?NS_COMMANDS, Lang) -> + ejabberd_hooks:run_fold(adhoc_sm_items, LServer, {result, []}, [From, To, Lang]); + +get_sm_commands(Acc, _From, _To, _Node, _Lang) -> + Acc. + +%------------------------------------------------------------------------- + +%% On disco info request to the ad-hoc node, return automation/command-list. +get_local_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) -> + [{xmlelement, "identity", + [{"category", "automation"}, + {"type", "command-list"}, + {"name", translate:translate(Lang, "Commands")}], []} | Acc]; + +get_local_identity(Acc, _From, _To, "ping", Lang) -> + [{xmlelement, "identity", + [{"category", "automation"}, + {"type", "command-node"}, + {"name", translate:translate(Lang, "Ping")}], []} | Acc]; + +get_local_identity(Acc, _From, _To, _Node, _Lang) -> + Acc. + +%------------------------------------------------------------------------- + +%% On disco info request to the ad-hoc node, return automation/command-list. +get_sm_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) -> + [{xmlelement, "identity", + [{"category", "automation"}, + {"type", "command-list"}, + {"name", translate:translate(Lang, "Commands")}], []} | Acc]; + +get_sm_identity(Acc, _From, _To, _Node, _Lang) -> + Acc. + +%------------------------------------------------------------------------- + +get_local_features(Acc, _From, _To, "", _Lang) -> + Feats = case Acc of + {result, I} -> I; + _ -> [] + end, + {result, Feats ++ [?NS_COMMANDS]}; + +get_local_features(_Acc, _From, _To, ?NS_COMMANDS, _Lang) -> + %% override all lesser features... + {result, []}; + +get_local_features(_Acc, _From, _To, "ping", _Lang) -> + %% override all lesser features... + {result, [?NS_COMMANDS]}; + +get_local_features(Acc, _From, _To, _Node, _Lang) -> + Acc. + +%------------------------------------------------------------------------- + +get_sm_features(Acc, _From, _To, "", _Lang) -> + Feats = case Acc of + {result, I} -> I; + _ -> [] + end, + {result, Feats ++ [?NS_COMMANDS]}; + +get_sm_features(_Acc, _From, _To, ?NS_COMMANDS, _Lang) -> + %% override all lesser features... + {result, []}; + +get_sm_features(Acc, _From, _To, _Node, _Lang) -> + Acc. + +%------------------------------------------------------------------------- + +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). + + +process_adhoc_request(From, To, #iq{sub_el = SubEl} = 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 -> + IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}; + {error, Error} -> + IQ#iq{type = error, sub_el = [SubEl, Error]}; + Command -> + IQ#iq{type = result, sub_el = [Command]} + end + end. + + +ping_item(Acc, _From, #jid{server = Server} = _To, Lang) -> + Items = case Acc of + {result, I} -> + I; + _ -> + [] + end, + Nodes = [{xmlelement, "item", + [{"jid", Server}, + {"node", "ping"}, + {"name", translate:translate(Lang, "Ping")}], + []}], + {result, Items ++ Nodes}. + + +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")}]}); + true -> + {error, ?ERR_BAD_REQUEST} + end; + +ping_command(Acc, _From, _To, _Request) -> + Acc. + |