2004-01-11 21:42:57 +01:00
|
|
|
%%%----------------------------------------------------------------------
|
|
|
|
%%% File : ejabberd_ctl.erl
|
2007-12-24 12:41:41 +01:00
|
|
|
%%% Author : Alexey Shchepin <alexey@process-one.net>
|
2004-01-11 21:42:57 +01:00
|
|
|
%%% Purpose : Ejabberd admin tool
|
2007-12-24 12:41:41 +01:00
|
|
|
%%% Created : 11 Jan 2004 by Alexey Shchepin <alexey@process-one.net>
|
|
|
|
%%%
|
|
|
|
%%%
|
2008-09-16 16:39:57 +02:00
|
|
|
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
2007-12-24 12:41:41 +01:00
|
|
|
%%%
|
|
|
|
%%% This program is free software; you can redistribute it and/or
|
|
|
|
%%% modify it under the terms of the GNU General Public License as
|
|
|
|
%%% published by the Free Software Foundation; either version 2 of the
|
|
|
|
%%% License, or (at your option) any later version.
|
|
|
|
%%%
|
|
|
|
%%% This program is distributed in the hope that it will be useful,
|
|
|
|
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
%%% General Public License for more details.
|
2008-09-16 16:39:57 +02:00
|
|
|
%%%
|
2007-12-24 12:41:41 +01:00
|
|
|
%%% You should have received a copy of the GNU General Public License
|
|
|
|
%%% along with this program; if not, write to the Free Software
|
|
|
|
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
|
|
%%% 02111-1307 USA
|
|
|
|
%%%
|
2004-01-11 21:42:57 +01:00
|
|
|
%%%----------------------------------------------------------------------
|
|
|
|
|
|
|
|
-module(ejabberd_ctl).
|
2007-12-24 12:41:41 +01:00
|
|
|
-author('alexey@process-one.net').
|
2004-01-11 21:42:57 +01:00
|
|
|
|
2006-02-13 05:02:59 +01:00
|
|
|
-export([start/0,
|
2006-02-20 05:07:42 +01:00
|
|
|
init/0,
|
2006-02-15 05:15:54 +01:00
|
|
|
process/1,
|
2008-07-11 14:48:27 +02:00
|
|
|
dump_to_textfile/1,
|
2006-02-15 05:15:54 +01:00
|
|
|
register_commands/3,
|
2006-02-20 05:07:42 +01:00
|
|
|
register_commands/4,
|
|
|
|
unregister_commands/3,
|
|
|
|
unregister_commands/4]).
|
2004-01-11 21:42:57 +01:00
|
|
|
|
2006-02-13 05:02:59 +01:00
|
|
|
-include("ejabberd_ctl.hrl").
|
2006-05-01 11:55:03 +02:00
|
|
|
-include("ejabberd.hrl").
|
2004-09-10 22:57:00 +02:00
|
|
|
|
2004-01-11 21:42:57 +01:00
|
|
|
start() ->
|
|
|
|
case init:get_plain_arguments() of
|
|
|
|
[SNode | Args] ->
|
2007-11-26 08:59:35 +01:00
|
|
|
SNode1 = case string:tokens(SNode, "@") of
|
|
|
|
[_Node, _Server] ->
|
|
|
|
SNode;
|
|
|
|
_ ->
|
|
|
|
case net_kernel:longnames() of
|
|
|
|
true ->
|
|
|
|
SNode ++ "@" ++ inet_db:gethostname() ++
|
|
|
|
"." ++ inet_db:res_option(domain);
|
|
|
|
false ->
|
|
|
|
SNode ++ "@" ++ inet_db:gethostname();
|
|
|
|
_ ->
|
|
|
|
SNode
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
Node = list_to_atom(SNode1),
|
2006-02-13 05:02:59 +01:00
|
|
|
Status = case rpc:call(Node, ?MODULE, process, [Args]) of
|
|
|
|
{badrpc, Reason} ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("RPC failed on the node ~p: ~p~n",
|
2006-02-13 05:02:59 +01:00
|
|
|
[Node, Reason]),
|
|
|
|
?STATUS_BADRPC;
|
|
|
|
S ->
|
|
|
|
S
|
|
|
|
end,
|
2004-09-10 22:57:00 +02:00
|
|
|
halt(Status);
|
2004-01-11 21:42:57 +01:00
|
|
|
_ ->
|
2004-09-10 22:57:00 +02:00
|
|
|
print_usage(),
|
|
|
|
halt(?STATUS_USAGE)
|
|
|
|
end.
|
|
|
|
|
2006-02-20 05:07:42 +01:00
|
|
|
init() ->
|
|
|
|
ets:new(ejabberd_ctl_cmds, [named_table, set, public]),
|
|
|
|
ets:new(ejabberd_ctl_host_cmds, [named_table, set, public]).
|
|
|
|
|
2004-01-11 21:42:57 +01:00
|
|
|
|
2006-02-13 05:02:59 +01:00
|
|
|
process(["status"]) ->
|
|
|
|
{InternalStatus, ProvidedStatus} = init:get_status(),
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("Node ~p is ~p. Status: ~p~n",
|
2006-04-27 00:28:05 +02:00
|
|
|
[node(), InternalStatus, ProvidedStatus]),
|
|
|
|
case lists:keysearch(ejabberd, 1, application:which_applications()) of
|
|
|
|
false ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("ejabberd is not running~n", []),
|
2006-04-27 00:28:05 +02:00
|
|
|
?STATUS_ERROR;
|
|
|
|
{value,_Version} ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("ejabberd is running~n", []),
|
2006-04-27 00:28:05 +02:00
|
|
|
?STATUS_SUCCESS
|
|
|
|
end;
|
2004-01-11 21:42:57 +01:00
|
|
|
|
2006-02-13 05:02:59 +01:00
|
|
|
process(["stop"]) ->
|
|
|
|
init:stop(),
|
|
|
|
?STATUS_SUCCESS;
|
2004-01-11 21:42:57 +01:00
|
|
|
|
2006-02-13 05:02:59 +01:00
|
|
|
process(["restart"]) ->
|
|
|
|
init:restart(),
|
|
|
|
?STATUS_SUCCESS;
|
2004-01-11 21:42:57 +01:00
|
|
|
|
2006-02-13 05:02:59 +01:00
|
|
|
process(["reopen-log"]) ->
|
2008-03-15 11:57:38 +01:00
|
|
|
ejabberd_hooks:run(reopen_log_hook, []),
|
2008-09-16 16:39:57 +02:00
|
|
|
lists:foreach(fun(Host) ->
|
|
|
|
ejabberd_hooks:run(reopen_log_hook, Host, [Host])
|
|
|
|
end, ?MYHOSTS),
|
2008-03-15 11:57:38 +01:00
|
|
|
%% TODO: Use the Reopen log API for logger_h ?
|
2006-02-13 05:02:59 +01:00
|
|
|
ejabberd_logger_h:reopen_log(),
|
|
|
|
?STATUS_SUCCESS;
|
2004-01-27 20:14:49 +01:00
|
|
|
|
2006-02-13 05:02:59 +01:00
|
|
|
process(["register", User, Server, Password]) ->
|
|
|
|
case ejabberd_auth:try_register(User, Server, Password) of
|
2004-01-11 21:42:57 +01:00
|
|
|
{atomic, ok} ->
|
2004-09-10 22:57:00 +02:00
|
|
|
?STATUS_SUCCESS;
|
2004-01-11 21:42:57 +01:00
|
|
|
{atomic, exists} ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("User ~p already registered at node ~p~n",
|
2006-02-13 05:02:59 +01:00
|
|
|
[User ++ "@" ++ Server, node()]),
|
2004-09-10 22:57:00 +02:00
|
|
|
?STATUS_ERROR;
|
2004-01-11 21:42:57 +01:00
|
|
|
{error, Reason} ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("Can't register user ~p at node ~p: ~p~n",
|
2006-02-13 05:02:59 +01:00
|
|
|
[User ++ "@" ++ Server, node(), Reason]),
|
|
|
|
?STATUS_ERROR
|
2004-01-11 21:42:57 +01:00
|
|
|
end;
|
|
|
|
|
2006-02-13 05:02:59 +01:00
|
|
|
process(["unregister", User, Server]) ->
|
|
|
|
case ejabberd_auth:remove_user(User, Server) of
|
2004-01-11 21:42:57 +01:00
|
|
|
{error, Reason} ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("Can't unregister user ~p at node ~p: ~p~n",
|
2006-02-13 05:02:59 +01:00
|
|
|
[User ++ "@" ++ Server, node(), Reason]),
|
2004-09-10 22:57:00 +02:00
|
|
|
?STATUS_ERROR;
|
2005-04-18 00:59:44 +02:00
|
|
|
_ ->
|
|
|
|
?STATUS_SUCCESS
|
2004-01-11 21:42:57 +01:00
|
|
|
end;
|
|
|
|
|
2006-02-13 05:02:59 +01:00
|
|
|
process(["backup", Path]) ->
|
|
|
|
case mnesia:backup(Path) of
|
2004-05-05 22:34:54 +02:00
|
|
|
ok ->
|
2004-09-10 22:57:00 +02:00
|
|
|
?STATUS_SUCCESS;
|
2004-01-18 21:42:09 +01:00
|
|
|
{error, Reason} ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("Can't store backup in ~p at node ~p: ~p~n",
|
2006-02-13 05:02:59 +01:00
|
|
|
[filename:absname(Path), node(), Reason]),
|
|
|
|
?STATUS_ERROR
|
2004-01-18 21:42:09 +01:00
|
|
|
end;
|
|
|
|
|
2006-02-13 05:02:59 +01:00
|
|
|
process(["dump", Path]) ->
|
|
|
|
case dump_to_textfile(Path) of
|
2004-05-05 22:34:54 +02:00
|
|
|
ok ->
|
2004-09-10 22:57:00 +02:00
|
|
|
?STATUS_SUCCESS;
|
2004-05-05 22:34:54 +02:00
|
|
|
{error, Reason} ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("Can't store dump in ~p at node ~p: ~p~n",
|
2006-02-13 05:02:59 +01:00
|
|
|
[filename:absname(Path), node(), Reason]),
|
|
|
|
?STATUS_ERROR
|
2004-05-05 22:34:54 +02:00
|
|
|
end;
|
|
|
|
|
2006-02-13 05:02:59 +01:00
|
|
|
process(["load", Path]) ->
|
|
|
|
case mnesia:load_textfile(Path) of
|
2005-04-27 01:11:16 +02:00
|
|
|
{atomic, ok} ->
|
2004-09-10 22:57:00 +02:00
|
|
|
?STATUS_SUCCESS;
|
2004-05-05 22:34:54 +02:00
|
|
|
{error, Reason} ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("Can't load dump in ~p at node ~p: ~p~n",
|
2006-02-13 05:02:59 +01:00
|
|
|
[filename:absname(Path), node(), Reason]),
|
|
|
|
?STATUS_ERROR
|
2004-05-05 22:34:54 +02:00
|
|
|
end;
|
|
|
|
|
2006-02-13 05:02:59 +01:00
|
|
|
process(["restore", Path]) ->
|
2008-09-16 16:39:57 +02:00
|
|
|
case ejabberd_admin:restore(Path) of
|
2005-04-17 23:39:41 +02:00
|
|
|
{atomic, _} ->
|
2004-09-10 22:57:00 +02:00
|
|
|
?STATUS_SUCCESS;
|
2004-01-18 21:42:09 +01:00
|
|
|
{error, Reason} ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("Can't restore backup from ~p at node ~p: ~p~n",
|
2006-02-13 05:02:59 +01:00
|
|
|
[filename:absname(Path), node(), Reason]),
|
2006-05-01 11:55:03 +02:00
|
|
|
?STATUS_ERROR;
|
|
|
|
{aborted,{no_exists,Table}} ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("Can't restore backup from ~p at node ~p: Table ~p does not exist.~n",
|
2006-05-07 19:31:12 +02:00
|
|
|
[filename:absname(Path), node(), Table]),
|
|
|
|
?STATUS_ERROR;
|
|
|
|
{aborted,enoent} ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("Can't restore backup from ~p at node ~p: File not found.~n",
|
2006-05-07 19:31:12 +02:00
|
|
|
[filename:absname(Path), node()]),
|
|
|
|
?STATUS_ERROR
|
2004-01-18 21:42:09 +01:00
|
|
|
end;
|
|
|
|
|
2006-02-13 05:02:59 +01:00
|
|
|
process(["install-fallback", Path]) ->
|
|
|
|
case mnesia:install_fallback(Path) of
|
2005-04-27 01:11:16 +02:00
|
|
|
ok ->
|
2004-09-10 22:57:00 +02:00
|
|
|
?STATUS_SUCCESS;
|
2004-01-18 21:42:09 +01:00
|
|
|
{error, Reason} ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("Can't install fallback from ~p at node ~p: ~p~n",
|
2006-02-13 05:02:59 +01:00
|
|
|
[filename:absname(Path), node(), Reason]),
|
|
|
|
?STATUS_ERROR
|
2004-01-18 21:42:09 +01:00
|
|
|
end;
|
|
|
|
|
2006-02-13 05:02:59 +01:00
|
|
|
process(["import-file", Path]) ->
|
|
|
|
case jd2ejd:import_file(Path) of
|
2005-05-23 21:47:57 +02:00
|
|
|
ok ->
|
|
|
|
?STATUS_SUCCESS;
|
|
|
|
{error, Reason} ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("Can't import jabberd 1.4 spool file ~p at node ~p: ~p~n",
|
2006-02-13 05:02:59 +01:00
|
|
|
[filename:absname(Path), node(), Reason]),
|
|
|
|
?STATUS_ERROR
|
2005-05-23 21:47:57 +02:00
|
|
|
end;
|
|
|
|
|
2006-02-13 05:02:59 +01:00
|
|
|
process(["import-dir", Path]) ->
|
|
|
|
case jd2ejd:import_dir(Path) of
|
2005-05-23 21:47:57 +02:00
|
|
|
ok ->
|
|
|
|
?STATUS_SUCCESS;
|
|
|
|
{error, Reason} ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("Can't import jabberd 1.4 spool dir ~p at node ~p: ~p~n",
|
2006-02-13 05:02:59 +01:00
|
|
|
[filename:absname(Path), node(), Reason]),
|
|
|
|
?STATUS_ERROR
|
2005-05-23 21:47:57 +02:00
|
|
|
end;
|
|
|
|
|
2006-02-13 05:02:59 +01:00
|
|
|
process(["delete-expired-messages"]) ->
|
|
|
|
mod_offline:remove_expired_messages(),
|
|
|
|
?STATUS_SUCCESS;
|
2004-05-05 22:34:54 +02:00
|
|
|
|
2007-12-21 22:50:22 +01:00
|
|
|
process(["mnesia"]) ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("~p~n", [mnesia:system_info(all)]),
|
2007-12-21 22:50:22 +01:00
|
|
|
?STATUS_SUCCESS;
|
|
|
|
|
|
|
|
process(["mnesia", "info"]) ->
|
|
|
|
mnesia:info(),
|
|
|
|
?STATUS_SUCCESS;
|
|
|
|
|
|
|
|
process(["mnesia", Arg]) when is_list(Arg) ->
|
|
|
|
case catch mnesia:system_info(list_to_atom(Arg)) of
|
2008-03-21 15:44:16 +01:00
|
|
|
{'EXIT', Error} -> ?PRINT("Error: ~p~n", [Error]);
|
|
|
|
Return -> ?PRINT("~p~n", [Return])
|
2007-12-21 22:50:22 +01:00
|
|
|
end,
|
|
|
|
?STATUS_SUCCESS;
|
|
|
|
|
2006-05-07 23:26:06 +02:00
|
|
|
process(["delete-old-messages", Days]) ->
|
|
|
|
case catch list_to_integer(Days) of
|
|
|
|
{'EXIT',{Reason, _Stack}} ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("Can't delete old messages (~p). Please pass an integer as parameter.~n",
|
2006-05-07 23:26:06 +02:00
|
|
|
[Reason]),
|
|
|
|
?STATUS_ERROR;
|
|
|
|
Integer when Integer >= 0 ->
|
|
|
|
{atomic, _} = mod_offline:remove_old_messages(Integer),
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("Removed messages older than ~s days~n", [Days]),
|
2006-05-07 23:26:06 +02:00
|
|
|
?STATUS_SUCCESS;
|
2006-12-15 22:26:47 +01:00
|
|
|
_Integer ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("Can't delete old messages. Please pass a positive integer as parameter.~n", []),
|
2006-05-07 23:26:06 +02:00
|
|
|
?STATUS_ERROR
|
|
|
|
end;
|
|
|
|
|
2006-02-20 05:07:42 +01:00
|
|
|
process(["vhost", H | Args]) ->
|
|
|
|
case jlib:nameprep(H) of
|
|
|
|
false ->
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT("Bad hostname: ~p~n", [H]),
|
2006-02-20 05:07:42 +01:00
|
|
|
?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;
|
|
|
|
|
2006-02-15 05:15:54 +01:00
|
|
|
process(Args) ->
|
2006-02-20 05:07:42 +01:00
|
|
|
case ejabberd_hooks:run_fold(ejabberd_ctl_process, false, [Args]) of
|
2006-02-15 05:15:54 +01:00
|
|
|
false ->
|
|
|
|
print_usage(),
|
|
|
|
?STATUS_USAGE;
|
|
|
|
Status ->
|
|
|
|
Status
|
|
|
|
end.
|
2004-01-11 21:42:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
print_usage() ->
|
2006-02-15 05:15:54 +01:00
|
|
|
CmdDescs =
|
|
|
|
[{"status", "get ejabberd status"},
|
|
|
|
{"stop", "stop ejabberd"},
|
|
|
|
{"restart", "restart ejabberd"},
|
|
|
|
{"reopen-log", "reopen log file"},
|
|
|
|
{"register user server password", "register a user"},
|
|
|
|
{"unregister user server", "unregister a user"},
|
|
|
|
{"backup file", "store a database backup to file"},
|
|
|
|
{"restore file", "restore a database backup from file"},
|
|
|
|
{"install-fallback file", "install a database fallback from file"},
|
|
|
|
{"dump file", "dump a database to a text file"},
|
|
|
|
{"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"},
|
2006-02-20 05:07:42 +01:00
|
|
|
{"delete-expired-messages", "delete expired offline messages from database"},
|
2006-05-07 23:26:06 +02:00
|
|
|
{"delete-old-messages n", "delete offline messages older than n days from database"},
|
2007-12-21 22:50:22 +01:00
|
|
|
{"mnesia [info]", "show information of Mnesia system"},
|
2006-02-20 05:07:42 +01:00
|
|
|
{"vhost host ...", "execute host-specific commands"}] ++
|
2006-02-15 05:15:54 +01:00
|
|
|
ets:tab2list(ejabberd_ctl_cmds),
|
|
|
|
MaxCmdLen =
|
|
|
|
lists:max(lists:map(
|
|
|
|
fun({Cmd, _Desc}) ->
|
|
|
|
length(Cmd)
|
|
|
|
end, CmdDescs)),
|
|
|
|
NewLine = io_lib:format("~n", []),
|
|
|
|
FmtCmdDescs =
|
|
|
|
lists:map(
|
|
|
|
fun({Cmd, Desc}) ->
|
2006-02-20 05:07:42 +01:00
|
|
|
[" ", Cmd, string:chars($\s, MaxCmdLen - length(Cmd) + 2),
|
2006-02-15 05:15:54 +01:00
|
|
|
Desc, NewLine]
|
|
|
|
end, CmdDescs),
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT(
|
2007-11-26 08:59:35 +01:00
|
|
|
"Usage: ejabberdctl [--node nodename] command [options]~n"
|
2004-05-05 22:34:54 +02:00
|
|
|
"~n"
|
2007-11-26 08:59:35 +01:00
|
|
|
"Available commands in this ejabberd node:~n"
|
2006-02-15 05:15:54 +01:00
|
|
|
++ FmtCmdDescs ++
|
2004-05-05 22:34:54 +02:00
|
|
|
"~n"
|
2007-11-26 08:59:35 +01:00
|
|
|
"Examples:~n"
|
|
|
|
" ejabberdctl restart~n"
|
|
|
|
" ejabberdctl --node ejabberd@host restart~n"
|
2008-03-21 15:44:16 +01:00
|
|
|
" ejabberdctl vhost jabber.example.org ...~n",
|
|
|
|
[]).
|
2005-04-27 01:11:16 +02:00
|
|
|
|
2006-02-20 05:07:42 +01:00
|
|
|
print_vhost_usage(Host) ->
|
|
|
|
CmdDescs =
|
|
|
|
ets:select(ejabberd_ctl_host_cmds,
|
2006-12-15 22:26:47 +01:00
|
|
|
[{{{Host, '$1'}, '$2'}, [], [{{'$1', '$2'}}]}]),
|
2006-02-20 05:07:42 +01:00
|
|
|
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),
|
2008-03-21 15:44:16 +01:00
|
|
|
?PRINT(
|
2007-11-26 08:59:35 +01:00
|
|
|
"Usage: ejabberdctl [--node nodename] vhost hostname command [options]~n"
|
2006-02-20 05:07:42 +01:00
|
|
|
"~n"
|
2007-11-26 08:59:35 +01:00
|
|
|
"Available commands in this ejabberd node and this vhost:~n"
|
2006-02-20 05:07:42 +01:00
|
|
|
++ FmtCmdDescs ++
|
|
|
|
"~n"
|
2007-11-26 08:59:35 +01:00
|
|
|
"Examples:~n"
|
2008-03-21 15:44:16 +01:00
|
|
|
" ejabberdctl vhost "++Host++" registered-users~n",
|
|
|
|
[]).
|
2006-02-20 05:07:42 +01:00
|
|
|
|
2006-02-15 05:15:54 +01:00
|
|
|
register_commands(CmdDescs, Module, Function) ->
|
|
|
|
ets:insert(ejabberd_ctl_cmds, CmdDescs),
|
|
|
|
ejabberd_hooks:add(ejabberd_ctl_process,
|
|
|
|
Module, Function, 50),
|
|
|
|
ok.
|
|
|
|
|
2006-02-20 05:07:42 +01:00
|
|
|
register_commands(Host, CmdDescs, Module, Function) ->
|
|
|
|
ets:insert(ejabberd_ctl_host_cmds,
|
2006-12-15 22:26:47 +01:00
|
|
|
[{{Host, Cmd}, Desc} || {Cmd, Desc} <- CmdDescs]),
|
2006-02-20 05:07:42 +01:00
|
|
|
ejabberd_hooks:add(ejabberd_ctl_process, Host,
|
|
|
|
Module, Function, 50),
|
|
|
|
ok.
|
|
|
|
|
2006-02-15 05:15:54 +01:00
|
|
|
unregister_commands(CmdDescs, Module, Function) ->
|
|
|
|
lists:foreach(fun(CmdDesc) ->
|
|
|
|
ets:delete_object(ejabberd_ctl_cmds, CmdDesc)
|
|
|
|
end, CmdDescs),
|
|
|
|
ejabberd_hooks:delete(ejabberd_ctl_process,
|
|
|
|
Module, Function, 50),
|
|
|
|
ok.
|
|
|
|
|
2006-02-20 05:07:42 +01:00
|
|
|
unregister_commands(Host, CmdDescs, Module, Function) ->
|
|
|
|
lists:foreach(fun({Cmd, Desc}) ->
|
|
|
|
ets:delete_object(ejabberd_ctl_host_cmds,
|
2006-12-15 22:26:47 +01:00
|
|
|
{{Host, Cmd}, Desc})
|
2006-02-20 05:07:42 +01:00
|
|
|
end, CmdDescs),
|
|
|
|
ejabberd_hooks:delete(ejabberd_ctl_process,
|
|
|
|
Module, Function, 50),
|
|
|
|
ok.
|
|
|
|
|
2005-04-27 01:11:16 +02:00
|
|
|
dump_to_textfile(File) ->
|
|
|
|
dump_to_textfile(mnesia:system_info(is_running), file:open(File, write)).
|
|
|
|
dump_to_textfile(yes, {ok, F}) ->
|
|
|
|
Tabs1 = lists:delete(schema, mnesia:system_info(local_tables)),
|
|
|
|
Tabs = lists:filter(
|
|
|
|
fun(T) ->
|
|
|
|
case mnesia:table_info(T, storage_type) of
|
|
|
|
disc_copies -> true;
|
|
|
|
disc_only_copies -> true;
|
|
|
|
_ -> false
|
|
|
|
end
|
|
|
|
end, Tabs1),
|
|
|
|
Defs = lists:map(
|
|
|
|
fun(T) -> {T, [{record_name, mnesia:table_info(T, record_name)},
|
2008-09-16 16:39:57 +02:00
|
|
|
{attributes, mnesia:table_info(T, attributes)}]}
|
2005-04-27 01:11:16 +02:00
|
|
|
end,
|
|
|
|
Tabs),
|
|
|
|
io:format(F, "~p.~n", [{tables, Defs}]),
|
|
|
|
lists:foreach(fun(T) -> dump_tab(F, T) end, Tabs),
|
|
|
|
file:close(F);
|
|
|
|
dump_to_textfile(_, {ok, F}) ->
|
|
|
|
file:close(F),
|
|
|
|
{error, mnesia_not_running};
|
|
|
|
dump_to_textfile(_, {error, Reason}) ->
|
|
|
|
{error, Reason}.
|
|
|
|
|
2006-02-13 05:02:59 +01:00
|
|
|
|
2005-04-27 01:11:16 +02:00
|
|
|
dump_tab(F, T) ->
|
|
|
|
W = mnesia:table_info(T, wild_pattern),
|
|
|
|
{atomic,All} = mnesia:transaction(
|
|
|
|
fun() -> mnesia:match_object(T, W, read) end),
|
|
|
|
lists:foreach(
|
|
|
|
fun(Term) -> io:format(F,"~p.~n", [setelement(1, Term, T)]) end, All).
|