diff --git a/src/ejabberd_admin.erl b/src/ejabberd_admin.erl index 5352ae1ee..4aa5faedb 100644 --- a/src/ejabberd_admin.erl +++ b/src/ejabberd_admin.erl @@ -51,7 +51,8 @@ install_fallback_mnesia/1, dump_to_textfile/1, dump_to_textfile/2, mnesia_change_nodename/4, - restore/1 % Still used by some modules + restore/1, % Still used by some modules + get_commands_spec/0 ]). -include("ejabberd.hrl"). @@ -59,16 +60,16 @@ -include("ejabberd_commands.hrl"). start() -> - ejabberd_commands:register_commands(commands()). + ejabberd_commands:register_commands(get_commands_spec()). stop() -> - ejabberd_commands:unregister_commands(commands()). + ejabberd_commands:unregister_commands(get_commands_spec()). %%% %%% ejabberd commands %%% -commands() -> +get_commands_spec() -> [ %% The commands status, stop and restart are implemented also in ejabberd_ctl %% They are defined here so that other interfaces can use them too diff --git a/src/ejabberd_commands.erl b/src/ejabberd_commands.erl index 547da028d..265d7141f 100644 --- a/src/ejabberd_commands.erl +++ b/src/ejabberd_commands.erl @@ -219,7 +219,8 @@ unregister_commands/1, execute_command/2, execute_command/4, - opt_type/1 + opt_type/1, + get_commands_spec/0 ]). -include("ejabberd_commands.hrl"). @@ -228,10 +229,8 @@ -define(POLICY_ACCESS, '$policy'). -init() -> - ets:new(ejabberd_commands, [named_table, set, public, - {keypos, #ejabberd_commands.name}]), - register_commands([ +get_commands_spec() -> + [ #ejabberd_commands{name = gen_html_doc_for_commands, tags = [documentation], desc = "Generates html documentation for ejabberd_commands", module = ejabberd_commands_doc, function = generate_html_output, @@ -259,7 +258,11 @@ init() -> "that will have example invocation include in markdown document"], result_desc = "0 if command failed, 1 when succedded", args_example = ["/home/me/docs/api.html", "mod_admin", "java,json"], - result_example = ok}]). + result_example = ok}]. +init() -> + ets:new(ejabberd_commands, [named_table, set, public, + {keypos, #ejabberd_commands.name}]), + register_commands(get_commands_spec()). -spec register_commands([ejabberd_commands()]) -> ok. diff --git a/src/ejabberd_commands_doc.erl b/src/ejabberd_commands_doc.erl index 999d4cd80..3368e3dec 100644 --- a/src/ejabberd_commands_doc.erl +++ b/src/ejabberd_commands_doc.erl @@ -5,7 +5,7 @@ %%% Created : 20 May 2008 by Badlop %%% %%% -%%% ejabberd, Copyright (C) 2002-2016 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -373,10 +373,27 @@ gen_doc(#ejabberd_commands{name=Name, tags=_Tags, desc=Desc, longdesc=LongDesc, ?TAG(h2, <<"Examples:">>), gen_calls(Cmd, HTMLOutput, Langs)]. +find_commands_definitions() -> + case code:lib_dir(ejabberd, ebin) of + {error, _} -> + lists:map(fun({N, _, _}) -> + ejabberd_commands:get_command_definition(N) + end, ejabberd_commands:list_commands()); + Path -> + lists:flatmap(fun(P) -> + Mod = list_to_atom(filename:rootname(P)), + code:ensure_loaded(Mod), + case erlang:function_exported(Mod, get_commands_spec, 0) of + true -> + apply(Mod, get_commands_spec, []); + _ -> + [] + end + end, filelib:wildcard("*.beam", Path)) + end. + generate_html_output(File, RegExp, Languages) -> - Cmds = lists:map(fun({N, _, _}) -> - ejabberd_commands:get_command_definition(N) - end, ejabberd_commands:list_commands()), + Cmds = find_commands_definitions(), {ok, RE} = re:compile(RegExp), Cmds2 = lists:filter(fun(#ejabberd_commands{name=Name, module=Module}) -> re:run(atom_to_list(Name), RE, [{capture, none}]) == match orelse @@ -393,9 +410,7 @@ generate_html_output(File, RegExp, Languages) -> ok. generate_md_output(File, RegExp, Languages) -> - Cmds = lists:map(fun({N, _, _}) -> - ejabberd_commands:get_command_definition(N) - end, ejabberd_commands:list_commands()), + Cmds = find_commands_definitions(), {ok, RE} = re:compile(RegExp), Cmds2 = lists:filter(fun(#ejabberd_commands{name=Name, module=Module}) -> re:run(atom_to_list(Name), RE, [{capture, none}]) == match orelse diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl index 06cad6af6..2f026b32a 100644 --- a/src/ejabberd_s2s.erl +++ b/src/ejabberd_s2s.erl @@ -42,7 +42,8 @@ clean_temporarily_blocked_table/0, list_temporarily_blocked_hosts/0, external_host_overloaded/1, is_temporarly_blocked/1, - check_peer_certificate/3]). + check_peer_certificate/3, + get_commands_spec/0]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, @@ -239,7 +240,7 @@ init([]) -> {attributes, record_info(fields, s2s)}]), mnesia:add_table_copy(s2s, node(), ram_copies), mnesia:subscribe(system), - ejabberd_commands:register_commands(commands()), + ejabberd_commands:register_commands(get_commands_spec()), mnesia:create_table(temporarily_blocked, [{ram_copies, [node()]}, {attributes, record_info(fields, temporarily_blocked)}]), @@ -265,7 +266,7 @@ handle_info({route, From, To, Packet}, State) -> handle_info(_Info, State) -> {noreply, State}. terminate(_Reason, _State) -> - ejabberd_commands:unregister_commands(commands()), + ejabberd_commands:unregister_commands(get_commands_spec()), ok. code_change(_OldVsn, State, _Extra) -> @@ -469,7 +470,7 @@ send_element(Pid, El) -> %%%---------------------------------------------------------------------- %%% ejabberd commands -commands() -> +get_commands_spec() -> [#ejabberd_commands{name = incoming_s2s_number, tags = [stats, s2s], desc = diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index ddc5697f2..3045a417b 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -63,7 +63,8 @@ get_user_ip/3, get_max_user_sessions/2, get_all_pids/0, - is_existing_resource/3 + is_existing_resource/3, + get_commands_spec/0 ]). -export([init/1, handle_call/3, handle_cast/2, @@ -323,7 +324,7 @@ init([]) -> ejabberd_hooks:add(remove_user, Host, ejabberd_sm, disconnect_removed_user, 100) end, ?MYHOSTS), - ejabberd_commands:register_commands(commands()), + ejabberd_commands:register_commands(get_commands_spec()), {ok, #state{}}. handle_call(_Request, _From, State) -> @@ -361,7 +362,7 @@ handle_info({unregister_iq_handler, Host, XMLNS}, handle_info(_Info, State) -> {noreply, State}. terminate(_Reason, _State) -> - ejabberd_commands:unregister_commands(commands()), + ejabberd_commands:unregister_commands(get_commands_spec()), ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. @@ -723,7 +724,7 @@ get_sm_backend() -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% ejabberd commands -commands() -> +get_commands_spec() -> [#ejabberd_commands{name = connected_users, tags = [session], desc = "List all established sessions", diff --git a/src/ext_mod.erl b/src/ext_mod.erl index c6fbf5096..46ece873c 100644 --- a/src/ext_mod.erl +++ b/src/ext_mod.erl @@ -33,7 +33,7 @@ installed_command/0, installed/0, installed/1, install/1, uninstall/1, upgrade/0, upgrade/1, add_sources/2, del_sources/1, modules_dir/0, - config_dir/0, opt_type/1]). + config_dir/0, opt_type/1, get_commands_spec/0]). -include("ejabberd_commands.hrl"). -include("logger.hrl"). @@ -46,12 +46,12 @@ start() -> [code:add_patha(module_ebin_dir(Module)) || {Module, _} <- installed()], application:start(inets), - ejabberd_commands:register_commands(commands()). + ejabberd_commands:register_commands(get_commands_spec()). stop() -> - ejabberd_commands:unregister_commands(commands()). + ejabberd_commands:unregister_commands(get_commands_spec()). -commands() -> +get_commands_spec() -> [#ejabberd_commands{name = modules_update_specs, tags = [admin,modules], desc = "", diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl index fed2a037a..dae775e47 100644 --- a/src/mod_admin_extra.erl +++ b/src/mod_admin_extra.erl @@ -47,7 +47,7 @@ srg_delete/2, srg_list/1, srg_get_info/2, srg_get_members/2, srg_user_add/4, srg_user_del/4, send_message/5, send_stanza/3, send_stanza_c2s/4, privacy_set/3, - stats/1, stats/2, mod_opt_type/1]). + stats/1, stats/2, mod_opt_type/1, get_commands_spec/0]). -include("ejabberd.hrl"). @@ -61,17 +61,17 @@ %%% start(_Host, _Opts) -> - ejabberd_commands:register_commands(commands()). + ejabberd_commands:register_commands(get_commands_spec()). stop(_Host) -> - ejabberd_commands:unregister_commands(commands()). + ejabberd_commands:unregister_commands(get_commands_spec()). %%% %%% Register commands %%% -commands() -> +get_commands_spec() -> Vcard1FieldsString = "Some vcard field names in get/set_vcard are:\n" " FN - Full Name\n" " NICKNAME - Nickname\n" diff --git a/src/mod_mam.erl b/src/mod_mam.erl index 88206716c..d6e4e9368 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -36,7 +36,8 @@ -export([user_send_packet/4, user_receive_packet/5, process_iq_v0_2/3, process_iq_v0_3/3, disco_sm_features/5, remove_user/2, remove_user/3, mod_opt_type/1, muc_process_iq/4, - muc_filter_message/5, message_is_archived/5, delete_old_messages/2]). + muc_filter_message/5, message_is_archived/5, delete_old_messages/2, + get_commands_spec/0]). -include_lib("stdlib/include/ms_transform.hrl"). -include("jlib.hrl"). @@ -116,7 +117,7 @@ start(Host, Opts) -> ejabberd_hooks:add(message_is_archived, Host, ?MODULE, message_is_archived, 50) end, - ejabberd_commands:register_commands(commands()), + ejabberd_commands:register_commands(get_commands_spec()), ok. init_db(mnesia, _Host) -> @@ -172,7 +173,7 @@ stop(Host) -> ejabberd_hooks:delete(message_is_archived, Host, ?MODULE, message_is_archived, 50) end, - ejabberd_commands:unregister_commands(commands()), + ejabberd_commands:unregister_commands(get_commands_spec()), ok. remove_user(User, Server) -> @@ -1364,7 +1365,7 @@ update(LServer, Table, Fields, Vals, Where) -> join([], _Sep) -> []; join([H | T], Sep) -> [H, [[Sep, X] || X <- T]]. -commands() -> +get_commands_spec() -> [#ejabberd_commands{name = delete_old_mam_messages, tags = [purge], desc = "Delete MAM messages older than DAYS", longdesc = "Valid message TYPEs: " diff --git a/src/mod_muc_admin.erl b/src/mod_muc_admin.erl index 603e96c65..c08757375 100644 --- a/src/mod_muc_admin.erl +++ b/src/mod_muc_admin.erl @@ -20,7 +20,7 @@ change_room_option/4, get_room_options/2, set_room_affiliation/4, get_room_affiliations/2, web_menu_main/2, web_page_main/2, web_menu_host/3, - web_page_host/3, mod_opt_type/1]). + web_page_host/3, mod_opt_type/1, get_commands_spec/0]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -36,14 +36,14 @@ %%---------------------------- start(Host, _Opts) -> - ejabberd_commands:register_commands(commands()), + ejabberd_commands:register_commands(get_commands_spec()), ejabberd_hooks:add(webadmin_menu_main, ?MODULE, web_menu_main, 50), ejabberd_hooks:add(webadmin_menu_host, Host, ?MODULE, web_menu_host, 50), ejabberd_hooks:add(webadmin_page_main, ?MODULE, web_page_main, 50), ejabberd_hooks:add(webadmin_page_host, Host, ?MODULE, web_page_host, 50). stop(Host) -> - ejabberd_commands:unregister_commands(commands()), + ejabberd_commands:unregister_commands(get_commands_spec()), ejabberd_hooks:delete(webadmin_menu_main, ?MODULE, web_menu_main, 50), ejabberd_hooks:delete(webadmin_menu_host, Host, ?MODULE, web_menu_host, 50), ejabberd_hooks:delete(webadmin_page_main, ?MODULE, web_page_main, 50), @@ -53,7 +53,7 @@ stop(Host) -> %%% Register commands %%% -commands() -> +get_commands_spec() -> [ #ejabberd_commands{name = muc_online_rooms, tags = [muc], desc = "List existing rooms ('global' to get all vhosts)",