From 80181dc618818a2a76dae76387e457d0dbbaa13d Mon Sep 17 00:00:00 2001 From: Alexey Shchepin Date: Mon, 20 Feb 2006 04:07:42 +0000 Subject: [PATCH] * src/ejabberd_ctl.erl: Added API for virtual host specific commands, removed registered-users command * src/ejabberd_auth.erl: Added processing of registered-users command * src/ejabberd_auth_internal.erl: Likewise * src/ejabberd_auth_ldap.erl: Likewise * src/ejabberd_auth_odbc.erl: Likewise * src/ejabberd_app.erl: Added inititalization of ejabberd_ctl * src/ejabberd_sm.erl: Minor update SVN Revision: 510 --- ChangeLog | 12 +++++ src/ejabberd_app.erl | 1 + src/ejabberd_auth.erl | 15 +++++- src/ejabberd_auth_internal.erl | 6 ++- src/ejabberd_auth_ldap.erl | 4 ++ src/ejabberd_auth_odbc.erl | 4 ++ src/ejabberd_ctl.erl | 98 +++++++++++++++++++++++++--------- src/ejabberd_sm.erl | 6 +-- 8 files changed, 116 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index f26f2e0a6..8c760f619 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2006-02-20 Alexey Shchepin + + * src/ejabberd_ctl.erl: Added API for virtual host specific + commands, removed registered-users command + * src/ejabberd_auth.erl: Added processing of registered-users + command + * src/ejabberd_auth_internal.erl: Likewise + * src/ejabberd_auth_ldap.erl: Likewise + * src/ejabberd_auth_odbc.erl: Likewise + * src/ejabberd_app.erl: Added inititalization of ejabberd_ctl + * src/ejabberd_sm.erl: Minor update + 2006-02-18 Alexey Shchepin * src/mod_irc/mod_irc_connection.erl: Added handling for "%", "&" diff --git a/src/ejabberd_app.erl b/src/ejabberd_app.erl index 109697470..c1ea274a2 100644 --- a/src/ejabberd_app.erl +++ b/src/ejabberd_app.erl @@ -24,6 +24,7 @@ start(normal, _Args) -> catch ssl:start(), translate:start(), acl:start(), + ejabberd_ctl:init(), gen_mod:start(), ejabberd_config:start(), Sup = ejabberd_sup:start_link(), diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl index d89d17563..045bf2726 100644 --- a/src/ejabberd_auth.erl +++ b/src/ejabberd_auth.erl @@ -23,10 +23,12 @@ is_user_exists/2, remove_user/2, remove_user/3, - plain_password_required/1 + plain_password_required/1, + ctl_process_get_registered/3 ]). -include("ejabberd.hrl"). +-include("ejabberd_ctl.hrl"). %%%---------------------------------------------------------------------- %%% API @@ -77,6 +79,17 @@ remove_user(User, Server) -> remove_user(User, Server, Password) -> (auth_module(Server)):remove_user(User, Server, Password). + +ctl_process_get_registered(_Val, Host, ["registered-users"]) -> + Users = ejabberd_auth:get_vh_registered_users(Host), + NewLine = io_lib:format("~n", []), + SUsers = lists:sort(Users), + FUsers = lists:map(fun({U, _S}) -> [U, NewLine] end, SUsers), + io:format("~s", [FUsers]), + {stop, ?STATUS_SUCCESS}; +ctl_process_get_registered(Val, _Host, _Args) -> + Val. + %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- diff --git a/src/ejabberd_auth_internal.erl b/src/ejabberd_auth_internal.erl index 1804f3eaa..62e765421 100644 --- a/src/ejabberd_auth_internal.erl +++ b/src/ejabberd_auth_internal.erl @@ -33,10 +33,14 @@ %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- -start(_Host) -> +start(Host) -> mnesia:create_table(passwd, [{disc_copies, [node()]}, {attributes, record_info(fields, passwd)}]), update_table(), + ejabberd_ctl:register_commands( + Host, + [{"registered-users", "list all registered users"}], + ejabberd_auth, ctl_process_get_registered), ok. plain_password_required() -> diff --git a/src/ejabberd_auth_ldap.erl b/src/ejabberd_auth_ldap.erl index 060b9b44b..6e454cb80 100644 --- a/src/ejabberd_auth_ldap.erl +++ b/src/ejabberd_auth_ldap.erl @@ -40,6 +40,10 @@ start(Host) -> LDAPServers, 389, RootDN, Password), eldap:start_link(get_eldap_id(Host, ejabberd_bind), LDAPServers, 389, RootDN, Password), + ejabberd_ctl:register_commands( + Host, + [{"registered-users", "list all registered users"}], + ejabberd_auth, ctl_process_get_registered), ok. plain_password_required() -> diff --git a/src/ejabberd_auth_odbc.erl b/src/ejabberd_auth_odbc.erl index a19ffd4e4..be1c8d4db 100644 --- a/src/ejabberd_auth_odbc.erl +++ b/src/ejabberd_auth_odbc.erl @@ -42,6 +42,10 @@ start(Host) -> supervisor, [ejabberd_odbc_sup]}, supervisor:start_child(ejabberd_sup, ChildSpec), + ejabberd_ctl:register_commands( + Host, + [{"registered-users", "list all registered users"}], + ejabberd_auth, ctl_process_get_registered), ok. plain_password_required() -> diff --git a/src/ejabberd_ctl.erl b/src/ejabberd_ctl.erl index b7e9b1f51..63825e916 100644 --- a/src/ejabberd_ctl.erl +++ b/src/ejabberd_ctl.erl @@ -10,9 +10,12 @@ -author('alexey@sevcom.net'). -export([start/0, + init/0, process/1, register_commands/3, - unregister_commands/3]). + register_commands/4, + unregister_commands/3, + unregister_commands/4]). -include("ejabberd_ctl.hrl"). @@ -34,6 +37,10 @@ start() -> halt(?STATUS_USAGE) end. +init() -> + ets:new(ejabberd_ctl_cmds, [named_table, set, public]), + ets:new(ejabberd_ctl_host_cmds, [named_table, set, public]). + process(["status"]) -> {InternalStatus, ProvidedStatus} = init:get_status(), @@ -147,29 +154,28 @@ process(["import-dir", Path]) -> ?STATUS_ERROR end; -process(["registered-users"]) -> - case ejabberd_auth:dirty_get_registered_users() of - Users when is_list(Users) -> - NewLine = io_lib:format("~n", []), - SUsers = lists:sort(Users), - FUsers = lists:map(fun({U, S}) -> [U, $@, S, NewLine] end, SUsers), - io:format("~s", [FUsers]), - ?STATUS_SUCCESS; - {error, Reason} -> - io:format("Can't get list of registered users at node ~p: ~p~n", - [node(), Reason]), - ?STATUS_ERROR - end; - process(["delete-expired-messages"]) -> mod_offline:remove_expired_messages(), ?STATUS_SUCCESS; +process(["vhost", H | Args]) -> + case jlib:nameprep(H) of + false -> + io:format("Bad hostname: ~p~n", [H]), + ?STATUS_ERROR; + Host -> + case ejabberd_hooks:run_fold( + ejabberd_ctl_process, Host, false, [Host, Args]) of + false -> + print_vhost_usage(Host), + ?STATUS_USAGE; + Status -> + Status + end + end; + process(Args) -> - case ejabberd_hooks:run_fold( - ejabberd_ctl_process, - false, - [Args]) of + case ejabberd_hooks:run_fold(ejabberd_ctl_process, false, [Args]) of false -> print_usage(), ?STATUS_USAGE; @@ -179,7 +185,6 @@ process(Args) -> print_usage() -> - catch ets:new(ejabberd_ctl_cmds, [named_table, ordered_set, public]), CmdDescs = [{"status", "get ejabberd status"}, {"stop", "stop ejabberd"}, @@ -194,8 +199,8 @@ print_usage() -> {"load file", "restore a database from a text file"}, {"import-file file", "import user data from jabberd 1.4 spool file"}, {"import-dir dir", "import user data from jabberd 1.4 spool directory"}, - {"registered-users", "list all registered users"}, - {"delete-expired-messages", "delete expired offline messages from database"}] ++ + {"delete-expired-messages", "delete expired offline messages from database"}, + {"vhost host ...", "execute host-specific commands"}] ++ ets:tab2list(ejabberd_ctl_cmds), MaxCmdLen = lists:max(lists:map( @@ -206,7 +211,7 @@ print_usage() -> FmtCmdDescs = lists:map( fun({Cmd, Desc}) -> - [" ", Cmd, string:chars($\s, MaxCmdLen - length(Cmd) + 1), + [" ", Cmd, string:chars($\s, MaxCmdLen - length(Cmd) + 2), Desc, NewLine] end, CmdDescs), io:format( @@ -219,15 +224,49 @@ print_usage() -> " ejabberdctl ejabberd@host restart~n" ). +print_vhost_usage(Host) -> + CmdDescs = + ets:select(ejabberd_ctl_host_cmds, + [{{Host, '$1', '$2'}, [], [{{'$1', '$2'}}]}]), + MaxCmdLen = + if + CmdDescs == [] -> + 0; + true -> + lists:max(lists:map( + fun({Cmd, _Desc}) -> + length(Cmd) + end, CmdDescs)) + end, + NewLine = io_lib:format("~n", []), + FmtCmdDescs = + lists:map( + fun({Cmd, Desc}) -> + [" ", Cmd, string:chars($\s, MaxCmdLen - length(Cmd) + 2), + Desc, NewLine] + end, CmdDescs), + io:format( + "Usage: ejabberdctl node vhost host command~n" + "~n" + "Available commands:~n" + ++ FmtCmdDescs ++ + "~n" + ). + register_commands(CmdDescs, Module, Function) -> - catch ets:new(ejabberd_ctl_cmds, [named_table, ordered_set, public]), ets:insert(ejabberd_ctl_cmds, CmdDescs), ejabberd_hooks:add(ejabberd_ctl_process, Module, Function, 50), ok. +register_commands(Host, CmdDescs, Module, Function) -> + ets:insert(ejabberd_ctl_host_cmds, + [{Host, Cmd, Desc} || {Cmd, Desc} <- CmdDescs]), + ejabberd_hooks:add(ejabberd_ctl_process, Host, + Module, Function, 50), + ok. + unregister_commands(CmdDescs, Module, Function) -> - catch ets:new(ejabberd_ctl_cmds, [named_table, ordered_set, public]), lists:foreach(fun(CmdDesc) -> ets:delete_object(ejabberd_ctl_cmds, CmdDesc) end, CmdDescs), @@ -235,6 +274,15 @@ unregister_commands(CmdDescs, Module, Function) -> Module, Function, 50), ok. +unregister_commands(Host, CmdDescs, Module, Function) -> + lists:foreach(fun({Cmd, Desc}) -> + ets:delete_object(ejabberd_ctl_host_cmds, + {Host, Cmd, Desc}) + end, CmdDescs), + ejabberd_hooks:delete(ejabberd_ctl_process, + Module, Function, 50), + ok. + dump_to_textfile(File) -> dump_to_textfile(mnesia:system_info(is_running), file:open(File, write)). dump_to_textfile(yes, {ok, F}) -> diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 2bdfa8faa..46880d013 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -535,18 +535,18 @@ ctl_process(_Val, ["connected-users"]) -> SUSRs = lists:sort(USRs), FUSRs = lists:map(fun({U, S, R}) -> [U, $@, S, $/, R, NewLine] end, SUSRs), io:format("~s", [FUSRs]), - ?STATUS_SUCCESS; + {stop, ?STATUS_SUCCESS}; ctl_process(_Val, ["connected-users-number"]) -> N = length(dirty_get_sessions_list()), io:format("~p~n", [N]), - ?STATUS_SUCCESS; + {stop, ?STATUS_SUCCESS}; ctl_process(_Val, ["user-resources", User, Server]) -> Resources = get_user_resources(User, Server), NewLine = io_lib:format("~n", []), SResources = lists:sort(Resources), FResources = lists:map(fun(R) -> [R, NewLine] end, SResources), io:format("~s", [FResources]), - ?STATUS_SUCCESS; + {stop, ?STATUS_SUCCESS}; ctl_process(Val, _Args) -> Val.