mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-30 17:43:57 +01:00
*** empty log message ***
SVN Revision: 43
This commit is contained in:
parent
c060093e84
commit
942fbb9fae
51
src/acl.erl
Normal file
51
src/acl.erl
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% File : acl.erl
|
||||||
|
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
%%% Purpose :
|
||||||
|
%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
%%% Id : $Id$
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(acl).
|
||||||
|
-author('alexey@sevcom.net').
|
||||||
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
|
-export([start/0, add/2, match_rule/2, match_acl/2]).
|
||||||
|
|
||||||
|
-include("ejabberd.hrl").
|
||||||
|
|
||||||
|
start() ->
|
||||||
|
ets:new(acls, [bag, named_table, public]).
|
||||||
|
|
||||||
|
|
||||||
|
add(ACLName, ACLData) ->
|
||||||
|
ets:insert(acls, {ACLName, ACLData}).
|
||||||
|
|
||||||
|
match_rule(Rule, JID) ->
|
||||||
|
ACLs = ejabberd_config:get_option(Rule),
|
||||||
|
match_acls(ACLs, JID).
|
||||||
|
|
||||||
|
match_acls([], _) ->
|
||||||
|
deny;
|
||||||
|
match_acls([{Access, ACL} | ACLs], JID) ->
|
||||||
|
case match_acl(ACL, JID) of
|
||||||
|
true ->
|
||||||
|
Access;
|
||||||
|
_ ->
|
||||||
|
match_acls(ACLs, JID)
|
||||||
|
end.
|
||||||
|
|
||||||
|
match_acl(ACL, JID) ->
|
||||||
|
{User, Server, Resource} = jlib:jid_tolower(JID),
|
||||||
|
lists:any(fun({_, Spec}) ->
|
||||||
|
case Spec of
|
||||||
|
all ->
|
||||||
|
true;
|
||||||
|
{user, U} ->
|
||||||
|
(U == User) and (?MYNAME == Server);
|
||||||
|
{user, U, S} ->
|
||||||
|
(U == User) and (S == Server);
|
||||||
|
{server, S} ->
|
||||||
|
S == Server
|
||||||
|
end
|
||||||
|
end, ets:lookup(acls, ACL)).
|
@ -1,5 +1,12 @@
|
|||||||
% $Id$
|
% $Id$
|
||||||
|
|
||||||
|
{acl, admin, {user, "aleksey"}}.
|
||||||
|
{acl, admin, {user, "ermine"}}.
|
||||||
|
{acl, jabberorg, {server, "jabber.org"}}.
|
||||||
|
{acl, aleksey, {user, "aleksey", "jabber.ru"}}.
|
||||||
|
|
||||||
|
{disco_admin, [{allow, admin},
|
||||||
|
{deny, all}]}.
|
||||||
|
|
||||||
{host, "e.localhost"}.
|
{host, "e.localhost"}.
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ start() ->
|
|||||||
|
|
||||||
init() ->
|
init() ->
|
||||||
register(ejabberd, self()),
|
register(ejabberd, self()),
|
||||||
erlang:system_flag(fullsweep_after, 0),
|
%erlang:system_flag(fullsweep_after, 0),
|
||||||
error_logger:logfile({open, ?ERROR_LOG_PATH}),
|
error_logger:logfile({open, ?ERROR_LOG_PATH}),
|
||||||
randoms:start(),
|
randoms:start(),
|
||||||
ok = erl_ddll:load_driver(".", expat_erl),
|
ok = erl_ddll:load_driver(".", expat_erl),
|
||||||
@ -27,6 +27,7 @@ init() ->
|
|||||||
db_init(),
|
db_init(),
|
||||||
sha:start(),
|
sha:start(),
|
||||||
translate:start(),
|
translate:start(),
|
||||||
|
acl:start(),
|
||||||
ejabberd_config:start(),
|
ejabberd_config:start(),
|
||||||
ejabberd_auth:start(),
|
ejabberd_auth:start(),
|
||||||
ejabberd_router:start(),
|
ejabberd_router:start(),
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
%%% Id : $Id$
|
%%% Id : $Id$
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
-define(VERSION, "0.0.1-alpha").
|
||||||
|
|
||||||
%-define(ejabberd_debug, true).
|
%-define(ejabberd_debug, true).
|
||||||
%-define(DBGFSM, true).
|
%-define(DBGFSM, true).
|
||||||
|
|
||||||
|
@ -22,13 +22,19 @@ start() ->
|
|||||||
load_file(File) ->
|
load_file(File) ->
|
||||||
case file:consult(File) of
|
case file:consult(File) of
|
||||||
{ok, Terms} ->
|
{ok, Terms} ->
|
||||||
lists:foreach(fun({Opt, Val}) ->
|
lists:foreach(fun process_term/1, Terms);
|
||||||
ets:insert(ejabberd_config, {Opt, Val})
|
|
||||||
end, Terms);
|
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
exit(file:format_error(Reason))
|
exit(file:format_error(Reason))
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
process_term(Term) ->
|
||||||
|
case Term of
|
||||||
|
{acl, ACLName, ACLData} ->
|
||||||
|
acl:add(ACLName, ACLData);
|
||||||
|
{Opt, Val} ->
|
||||||
|
ets:insert(ejabberd_config, {Opt, Val})
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
get_option(Opt) ->
|
get_option(Opt) ->
|
||||||
case ets:lookup(ejabberd_config, Opt) of
|
case ets:lookup(ejabberd_config, Opt) of
|
||||||
|
@ -28,6 +28,8 @@ start() ->
|
|||||||
mod_offline:start(),
|
mod_offline:start(),
|
||||||
mod_echo:start(),
|
mod_echo:start(),
|
||||||
mod_private:start(),
|
mod_private:start(),
|
||||||
|
mod_time:start(),
|
||||||
|
mod_version:start(),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
init() ->
|
init() ->
|
||||||
@ -60,10 +62,8 @@ do_route(State, From, To, Packet) ->
|
|||||||
"message" ->
|
"message" ->
|
||||||
ok;
|
ok;
|
||||||
"presence" ->
|
"presence" ->
|
||||||
% TODO
|
|
||||||
ok;
|
ok;
|
||||||
_ ->
|
_ ->
|
||||||
% DROP
|
|
||||||
ok
|
ok
|
||||||
end;
|
end;
|
||||||
{"", _, _} ->
|
{"", _, _} ->
|
||||||
|
@ -101,9 +101,10 @@ loop() ->
|
|||||||
do_route(From, To, Packet) ->
|
do_route(From, To, Packet) ->
|
||||||
?DEBUG("route~n\tfrom ~p~n\tto ~p~n\tpacket ~p~n", [From, To, Packet]),
|
?DEBUG("route~n\tfrom ~p~n\tto ~p~n\tpacket ~p~n", [From, To, Packet]),
|
||||||
{DstNode, DstDomain, DstResourse} = To,
|
{DstNode, DstDomain, DstResourse} = To,
|
||||||
case mnesia:dirty_read({local_route, DstDomain}) of
|
LDstDomain = jlib:tolower(DstDomain),
|
||||||
|
case mnesia:dirty_read({local_route, LDstDomain}) of
|
||||||
[] ->
|
[] ->
|
||||||
case mnesia:dirty_read({route, DstDomain}) of
|
case mnesia:dirty_read({route, LDstDomain}) of
|
||||||
[] ->
|
[] ->
|
||||||
ejabberd_s2s ! {route, From, To, Packet};
|
ejabberd_s2s ! {route, From, To, Packet};
|
||||||
[R] ->
|
[R] ->
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
set_presence/3,
|
set_presence/3,
|
||||||
unset_presence/2,
|
unset_presence/2,
|
||||||
dirty_get_sessions_list/0,
|
dirty_get_sessions_list/0,
|
||||||
|
dirty_get_my_sessions_list/0,
|
||||||
register_iq_handler/3]).
|
register_iq_handler/3]).
|
||||||
|
|
||||||
-include_lib("mnemosyne/include/mnemosyne.hrl").
|
-include_lib("mnemosyne/include/mnemosyne.hrl").
|
||||||
@ -250,8 +251,8 @@ do_route(From, To, Packet) ->
|
|||||||
ok
|
ok
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
UR = {User, Resource},
|
LUR = {jlib:tolower(User), Resource},
|
||||||
Sess = mnesia:dirty_read({session, UR}),
|
Sess = mnesia:dirty_read({session, LUR}),
|
||||||
case Sess of
|
case Sess of
|
||||||
[] ->
|
[] ->
|
||||||
if
|
if
|
||||||
@ -261,7 +262,7 @@ do_route(From, To, Packet) ->
|
|||||||
?DEBUG("packet droped~n", [])
|
?DEBUG("packet droped~n", [])
|
||||||
end;
|
end;
|
||||||
[Ses] ->
|
[Ses] ->
|
||||||
case mnesia:dirty_read({mysession, UR}) of
|
case mnesia:dirty_read({mysession, LUR}) of
|
||||||
[] ->
|
[] ->
|
||||||
Node = Ses#session.node,
|
Node = Ses#session.node,
|
||||||
?DEBUG("sending to node ~p~n", [Node]),
|
?DEBUG("sending to node ~p~n", [Node]),
|
||||||
@ -344,6 +345,9 @@ get_user_present_resources(User) ->
|
|||||||
dirty_get_sessions_list() ->
|
dirty_get_sessions_list() ->
|
||||||
mnesia:dirty_all_keys(session).
|
mnesia:dirty_all_keys(session).
|
||||||
|
|
||||||
|
dirty_get_my_sessions_list() ->
|
||||||
|
mnesia:dirty_all_keys(mysession).
|
||||||
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
is_iq_request_type/1,
|
is_iq_request_type/1,
|
||||||
iq_to_xml/1,
|
iq_to_xml/1,
|
||||||
parse_xdata_submit/1,
|
parse_xdata_submit/1,
|
||||||
|
timestamp_to_iso/1,
|
||||||
timestamp_to_xml/1]).
|
timestamp_to_xml/1]).
|
||||||
|
|
||||||
-include("namespaces.hrl").
|
-include("namespaces.hrl").
|
||||||
@ -293,6 +294,11 @@ parse_xdata_values([_ | Els], Res) ->
|
|||||||
parse_xdata_values(Els, Res).
|
parse_xdata_values(Els, Res).
|
||||||
|
|
||||||
|
|
||||||
|
timestamp_to_iso({{Year, Month, Day}, {Hour, Minute, Second}}) ->
|
||||||
|
lists:flatten(
|
||||||
|
io_lib:format("~4..0w~2..0w~2..0wT~2..0w:~2..0w:~2..0w",
|
||||||
|
[Year, Month, Day, Hour, Minute, Second])).
|
||||||
|
|
||||||
timestamp_to_xml({{Year, Month, Day}, {Hour, Minute, Second}}) ->
|
timestamp_to_xml({{Year, Month, Day}, {Hour, Minute, Second}}) ->
|
||||||
{xmlelement, "x",
|
{xmlelement, "x",
|
||||||
[{"xmlns", ?NS_DELAY},
|
[{"xmlns", ?NS_DELAY},
|
||||||
@ -300,3 +306,4 @@ timestamp_to_xml({{Year, Month, Day}, {Hour, Minute, Second}}) ->
|
|||||||
io_lib:format("~4..0w~2..0w~2..0wT~2..0w:~2..0w:~2..0w",
|
io_lib:format("~4..0w~2..0w~2..0wT~2..0w:~2..0w:~2..0w",
|
||||||
[Year, Month, Day, Hour, Minute, Second]))}],
|
[Year, Month, Day, Hour, Minute, Second]))}],
|
||||||
[]}.
|
[]}.
|
||||||
|
|
||||||
|
@ -53,55 +53,19 @@ process_local_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
|||||||
[{"code", "405"}],
|
[{"code", "405"}],
|
||||||
[{xmlcdata, "Not Allowed"}]}]};
|
[{xmlcdata, "Not Allowed"}]}]};
|
||||||
get ->
|
get ->
|
||||||
case string:tokens(xml:get_tag_attr_s("node", SubEl), "/") of
|
Node = string:tokens(xml:get_tag_attr_s("node", SubEl), "/"),
|
||||||
[] ->
|
|
||||||
Domains =
|
case get_local_items(Node, jlib:jid_to_string(To), Lang) of
|
||||||
lists:map(fun domain_to_xml/1,
|
{result, Res} ->
|
||||||
ejabberd_router:dirty_get_all_routes()),
|
|
||||||
{iq, ID, result, XMLNS,
|
|
||||||
[{xmlelement,
|
|
||||||
"query",
|
|
||||||
[{"xmlns", ?NS_DISCO_ITEMS}],
|
|
||||||
Domains ++
|
|
||||||
[{xmlelement, "item",
|
|
||||||
[{"jid", jlib:jid_to_string(To)},
|
|
||||||
{"name", translate:translate(Lang, "Online Users")},
|
|
||||||
{"node", "online users"}], []},
|
|
||||||
{xmlelement, "item",
|
|
||||||
[{"jid", jlib:jid_to_string(To)},
|
|
||||||
{"name", translate:translate(Lang, "All Users")},
|
|
||||||
{"node", "all users"}], []},
|
|
||||||
{xmlelement, "item",
|
|
||||||
[{"jid", jlib:jid_to_string(To)},
|
|
||||||
{"name", translate:translate(
|
|
||||||
Lang, "Outgoing S2S connections")},
|
|
||||||
{"node", "outgoing s2s"}], []}
|
|
||||||
]}]};
|
|
||||||
["online users"] ->
|
|
||||||
{iq, ID, result, XMLNS,
|
{iq, ID, result, XMLNS,
|
||||||
[{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
|
[{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
|
||||||
get_online_users()
|
Res
|
||||||
}]};
|
}]};
|
||||||
["all users"] ->
|
{error, Code, Desc} ->
|
||||||
{iq, ID, result, XMLNS,
|
|
||||||
[{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
|
|
||||||
get_all_users()
|
|
||||||
}]};
|
|
||||||
["outgoing s2s"] ->
|
|
||||||
{iq, ID, result, XMLNS,
|
|
||||||
[{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
|
|
||||||
get_outgoing_s2s(Lang)
|
|
||||||
}]};
|
|
||||||
["outgoing s2s", Host] ->
|
|
||||||
{iq, ID, result, XMLNS,
|
|
||||||
[{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
|
|
||||||
get_outgoing_s2s(Lang, Host)
|
|
||||||
}]};
|
|
||||||
_ ->
|
|
||||||
{iq, ID, error, XMLNS,
|
{iq, ID, error, XMLNS,
|
||||||
[SubEl, {xmlelement, "error",
|
[SubEl, {xmlelement, "error",
|
||||||
[{"code", "501"}],
|
[{"code", Code}],
|
||||||
[{xmlcdata, "Not Implemented"}]}]}
|
[{xmlcdata, Desc}]}]}
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@ -129,6 +93,19 @@ process_local_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
|||||||
["online users"] -> ?EMPTY_INFO_RESULT;
|
["online users"] -> ?EMPTY_INFO_RESULT;
|
||||||
["all users"] -> ?EMPTY_INFO_RESULT;
|
["all users"] -> ?EMPTY_INFO_RESULT;
|
||||||
["outgoing s2s" | _] -> ?EMPTY_INFO_RESULT;
|
["outgoing s2s" | _] -> ?EMPTY_INFO_RESULT;
|
||||||
|
["running nodes"] -> ?EMPTY_INFO_RESULT;
|
||||||
|
["stopped nodes"] -> ?EMPTY_INFO_RESULT;
|
||||||
|
["running nodes", ENode] ->
|
||||||
|
{iq, ID, result, XMLNS, [{xmlelement,
|
||||||
|
"query",
|
||||||
|
[{"xmlns", ?NS_DISCO_INFO}],
|
||||||
|
[{xmlelement, "identity",
|
||||||
|
[{"category", "ejabberd"},
|
||||||
|
{"type", "node"},
|
||||||
|
{"name", ENode}], []},
|
||||||
|
feature_to_xml({?NS_STATS})
|
||||||
|
]
|
||||||
|
}]};
|
||||||
_ ->
|
_ ->
|
||||||
{iq, ID, error, XMLNS,
|
{iq, ID, error, XMLNS,
|
||||||
[SubEl, {xmlelement, "error",
|
[SubEl, {xmlelement, "error",
|
||||||
@ -145,6 +122,51 @@ domain_to_xml(Domain) ->
|
|||||||
{xmlelement, "item", [{"jid", Domain}], []}.
|
{xmlelement, "item", [{"jid", Domain}], []}.
|
||||||
|
|
||||||
|
|
||||||
|
-define(TOP_NODE(Name, Node),
|
||||||
|
{xmlelement, "item",
|
||||||
|
[{"jid", Server},
|
||||||
|
{"name", translate:translate(Lang, Name)},
|
||||||
|
{"node", Node}], []}).
|
||||||
|
|
||||||
|
|
||||||
|
get_local_items([], Server, Lang) ->
|
||||||
|
Domains =
|
||||||
|
lists:map(fun domain_to_xml/1,
|
||||||
|
ejabberd_router:dirty_get_all_routes()),
|
||||||
|
{result,
|
||||||
|
Domains ++
|
||||||
|
[?TOP_NODE("Online Users", "online users"),
|
||||||
|
?TOP_NODE("All Users", "all users"),
|
||||||
|
?TOP_NODE("Outgoing S2S connections", "outgoing s2s"),
|
||||||
|
?TOP_NODE("Running Nodes", "running nodes"),
|
||||||
|
?TOP_NODE("Stopped Nodes", "stopped nodes")
|
||||||
|
]};
|
||||||
|
|
||||||
|
get_local_items(["online users"], Server, Lang) ->
|
||||||
|
{result, get_online_users()};
|
||||||
|
|
||||||
|
get_local_items(["all users"], Server, Lang) ->
|
||||||
|
{result, get_all_users()};
|
||||||
|
|
||||||
|
get_local_items(["outgoing s2s"], Server, Lang) ->
|
||||||
|
{result, get_outgoing_s2s(Lang)};
|
||||||
|
|
||||||
|
get_local_items(["running nodes"], Server, Lang) ->
|
||||||
|
{result, get_running_nodes(Lang)};
|
||||||
|
|
||||||
|
get_local_items(["stopped nodes"], Server, Lang) ->
|
||||||
|
{result, get_stopped_nodes(Lang)};
|
||||||
|
|
||||||
|
get_local_items(["running nodes", _], Server, Lang) ->
|
||||||
|
{result, []};
|
||||||
|
|
||||||
|
get_local_items(_, _, _) ->
|
||||||
|
{error, "501", "Not Implemented"}.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
get_online_users() ->
|
get_online_users() ->
|
||||||
case catch ejabberd_sm:dirty_get_sessions_list() of
|
case catch ejabberd_sm:dirty_get_sessions_list() of
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
@ -208,6 +230,44 @@ get_outgoing_s2s(Lang, To) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
get_running_nodes(Lang) ->
|
||||||
|
case catch mnesia:system_info(running_db_nodes) of
|
||||||
|
{'EXIT', Reason} ->
|
||||||
|
[];
|
||||||
|
DBNodes ->
|
||||||
|
lists:map(
|
||||||
|
fun(N) ->
|
||||||
|
S = atom_to_list(N),
|
||||||
|
{xmlelement, "item",
|
||||||
|
[{"jid", ?MYNAME},
|
||||||
|
{"node", "running nodes/" ++ S},
|
||||||
|
{"name", S}],
|
||||||
|
[]}
|
||||||
|
end, lists:sort(DBNodes))
|
||||||
|
end.
|
||||||
|
|
||||||
|
get_stopped_nodes(Lang) ->
|
||||||
|
case catch (lists:usort(mnesia:system_info(db_nodes) ++
|
||||||
|
mnesia:system_info(extra_db_nodes)) --
|
||||||
|
mnesia:system_info(running_db_nodes)) of
|
||||||
|
{'EXIT', Reason} ->
|
||||||
|
[];
|
||||||
|
DBNodes ->
|
||||||
|
lists:map(
|
||||||
|
fun(N) ->
|
||||||
|
S = atom_to_list(N),
|
||||||
|
{xmlelement, "item",
|
||||||
|
[{"jid", ?MYNAME},
|
||||||
|
{"node", "stopped nodes/" ++ S},
|
||||||
|
{"name", S}],
|
||||||
|
[]}
|
||||||
|
end, lists:sort(DBNodes))
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
process_sm_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
process_sm_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||||
{User, _, _} = To,
|
{User, _, _} = To,
|
||||||
case Type of
|
case Type of
|
||||||
|
@ -31,49 +31,16 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
|||||||
Node = string:tokens(xml:get_tag_attr_s("node", SubEl), "/"),
|
Node = string:tokens(xml:get_tag_attr_s("node", SubEl), "/"),
|
||||||
Names = get_names(Els, []),
|
Names = get_names(Els, []),
|
||||||
|
|
||||||
{T, Res} = get_local_stats(Node, Names),
|
case get_local_stats(Node, Names) of
|
||||||
case T of
|
{result, Res} ->
|
||||||
result ->
|
{iq, ID, result, XMLNS,
|
||||||
{iq, ID, result, ?NS_STATS, Res};
|
[{xmlelement, "query", [{"xmlns", XMLNS}], Res}]};
|
||||||
error ->
|
{error, Code, Desc} ->
|
||||||
{iq, ID, error, ?NS_STATS, [SubEl ++ Res]}
|
{iq, ID, error, XMLNS,
|
||||||
|
[SubEl, {xmlelement, "error",
|
||||||
|
[{"code", Code}],
|
||||||
|
[{xmlcdata, Desc}]}]}
|
||||||
end
|
end
|
||||||
|
|
||||||
%case Node of
|
|
||||||
%[] ->
|
|
||||||
% {iq, ID, result, XMLNS,
|
|
||||||
% [{xmlelement,
|
|
||||||
% "query",
|
|
||||||
% [{"xmlns", ?NS_STATS}],
|
|
||||||
% [{xmlelement, "stat", [{"name", "time/uptime"}], []},
|
|
||||||
% {xmlelement, "stat", [{"name", "time/cputime"}], []}
|
|
||||||
% ]}]};
|
|
||||||
%["online users"] ->
|
|
||||||
% {iq, ID, result, XMLNS,
|
|
||||||
% [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
|
|
||||||
% get_online_users()
|
|
||||||
% }]};
|
|
||||||
%["all users"] ->
|
|
||||||
% {iq, ID, result, XMLNS,
|
|
||||||
% [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
|
|
||||||
% get_all_users()
|
|
||||||
% }]};
|
|
||||||
%["outgoing s2s"] ->
|
|
||||||
% {iq, ID, result, XMLNS,
|
|
||||||
% [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
|
|
||||||
% get_outgoing_s2s(Lang)
|
|
||||||
% }]};
|
|
||||||
%["outgoing s2s", Host] ->
|
|
||||||
% {iq, ID, result, XMLNS,
|
|
||||||
% [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
|
|
||||||
% get_outgoing_s2s(Lang, Host)
|
|
||||||
% }]};
|
|
||||||
%_ ->
|
|
||||||
% {iq, ID, error, XMLNS,
|
|
||||||
% [SubEl, {xmlelement, "error",
|
|
||||||
% [{"code", "501"}],
|
|
||||||
% [{xmlcdata, "Not Implemented"}]}]}
|
|
||||||
%end
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
@ -91,31 +58,39 @@ get_names([_ | Els], Res) ->
|
|||||||
get_names(Els, Res).
|
get_names(Els, Res).
|
||||||
|
|
||||||
|
|
||||||
|
-define(STAT(Name), {xmlelement, "stat", [{"name", Name}], []}).
|
||||||
|
|
||||||
get_local_stats([], []) ->
|
get_local_stats([], []) ->
|
||||||
{result,
|
{result,
|
||||||
[{xmlelement,
|
[?STAT("users/online"),
|
||||||
"query",
|
?STAT("users/total")
|
||||||
[{"xmlns", ?NS_STATS}],
|
]};
|
||||||
[{xmlelement, "stat", [{"name", "time/uptime"}], []},
|
|
||||||
{xmlelement, "stat", [{"name", "time/cputime"}], []},
|
|
||||||
{xmlelement, "stat", [{"name", "users/online"}], []},
|
|
||||||
{xmlelement, "stat", [{"name", "users/total"}], []}
|
|
||||||
]}]};
|
|
||||||
get_local_stats([], Names) ->
|
get_local_stats([], Names) ->
|
||||||
|
{result, lists:map(fun(Name) -> get_local_stat([], Name) end, Names)};
|
||||||
|
|
||||||
|
get_local_stats(["running nodes", _], []) ->
|
||||||
{result,
|
{result,
|
||||||
[{xmlelement,
|
[?STAT("time/uptime"),
|
||||||
"query",
|
?STAT("time/cputime"),
|
||||||
[{"xmlns", ?NS_STATS}],
|
?STAT("users/online")
|
||||||
lists:map(fun(Name) -> get_local_stat([], Name) end, Names)
|
]};
|
||||||
}]};
|
|
||||||
|
get_local_stats(["running nodes", ENode], Names) ->
|
||||||
|
case search_running_node(ENode) of
|
||||||
|
false ->
|
||||||
|
{error, "404", "Not Found"};
|
||||||
|
Node ->
|
||||||
|
{result,
|
||||||
|
lists:map(fun(Name) -> get_node_stat(Node, Name) end, Names)}
|
||||||
|
end;
|
||||||
|
|
||||||
get_local_stats(_, _) ->
|
get_local_stats(_, _) ->
|
||||||
{error,
|
{error, "501", "Not Implemented"}.
|
||||||
[{xmlelement, "error",
|
|
||||||
[{"code", "501"}],
|
|
||||||
[{xmlcdata, "Not Implemented"}]}]}.
|
|
||||||
|
|
||||||
|
|
||||||
-define(STAT(Val, Unit),
|
|
||||||
|
-define(STATVAL(Val, Unit),
|
||||||
{xmlelement, "stat",
|
{xmlelement, "stat",
|
||||||
[{"name", Name},
|
[{"name", Name},
|
||||||
{"units", Unit},
|
{"units", Unit},
|
||||||
@ -130,25 +105,70 @@ get_local_stats(_, _) ->
|
|||||||
[{xmlcdata, Desc}]}]}).
|
[{xmlcdata, Desc}]}]}).
|
||||||
|
|
||||||
|
|
||||||
get_local_stat([], Name) when Name == "time/uptime" ->
|
%get_local_stat([], Name) when Name == "time/uptime" ->
|
||||||
?STAT(io_lib:format("~.3f", [element(1, statistics(wall_clock))/1000]),
|
% ?STATVAL(io_lib:format("~.3f", [element(1, statistics(wall_clock))/1000]),
|
||||||
"seconds");
|
% "seconds");
|
||||||
get_local_stat([], Name) when Name == "time/cputime" ->
|
%get_local_stat([], Name) when Name == "time/cputime" ->
|
||||||
?STAT(io_lib:format("~.3f", [element(1, statistics(runtime))/1000]),
|
% ?STATVAL(io_lib:format("~.3f", [element(1, statistics(runtime))/1000]),
|
||||||
"seconds");
|
% "seconds");
|
||||||
get_local_stat([], Name) when Name == "users/online" ->
|
get_local_stat([], Name) when Name == "users/online" ->
|
||||||
case catch ejabberd_sm:dirty_get_sessions_list() of
|
case catch ejabberd_sm:dirty_get_sessions_list() of
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
?STATERR("500", "Internal Server Error");
|
?STATERR("500", "Internal Server Error");
|
||||||
Users ->
|
Users ->
|
||||||
?STAT(integer_to_list(length(Users)), "users")
|
?STATVAL(integer_to_list(length(Users)), "users")
|
||||||
end;
|
end;
|
||||||
get_local_stat([], Name) when Name == "users/total" ->
|
get_local_stat([], Name) when Name == "users/total" ->
|
||||||
case catch ejabberd_auth:dirty_get_registered_users() of
|
case catch ejabberd_auth:dirty_get_registered_users() of
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
?STATERR("500", "Internal Server Error");
|
?STATERR("500", "Internal Server Error");
|
||||||
Users ->
|
Users ->
|
||||||
?STAT(integer_to_list(length(Users)), "users")
|
?STATVAL(integer_to_list(length(Users)), "users")
|
||||||
end;
|
end;
|
||||||
get_local_stat(_, Name) ->
|
get_local_stat(_, Name) ->
|
||||||
?STATERR("404", "Not Found").
|
?STATERR("404", "Not Found").
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
get_node_stat(Node, Name) when Name == "time/uptime" ->
|
||||||
|
case catch rpc:call(Node, erlang, statistics, [wall_clock]) of
|
||||||
|
{badrpc, Reason} ->
|
||||||
|
?STATERR("500", "Internal Server Error");
|
||||||
|
CPUTime ->
|
||||||
|
?STATVAL(
|
||||||
|
io_lib:format("~.3f", [element(1, CPUTime)/1000]), "seconds")
|
||||||
|
end;
|
||||||
|
|
||||||
|
get_node_stat(Node, Name) when Name == "time/cputime" ->
|
||||||
|
case catch rpc:call(Node, erlang, statistics, [runtime]) of
|
||||||
|
{badrpc, Reason} ->
|
||||||
|
?STATERR("500", "Internal Server Error");
|
||||||
|
RunTime ->
|
||||||
|
?STATVAL(
|
||||||
|
io_lib:format("~.3f", [element(1, RunTime)/1000]), "seconds")
|
||||||
|
end;
|
||||||
|
|
||||||
|
get_node_stat(Node, Name) when Name == "users/online" ->
|
||||||
|
case catch rpc:call(Node, ejabberd_sm, dirty_get_my_sessions_list, []) of
|
||||||
|
{badrpc, Reason} ->
|
||||||
|
?STATERR("500", "Internal Server Error");
|
||||||
|
Users ->
|
||||||
|
?STATVAL(integer_to_list(length(Users)), "users")
|
||||||
|
end;
|
||||||
|
get_node_stat(_, Name) ->
|
||||||
|
?STATERR("404", "Not Found").
|
||||||
|
|
||||||
|
|
||||||
|
search_running_node(SNode) ->
|
||||||
|
search_running_node(SNode, mnesia:system_info(running_db_nodes)).
|
||||||
|
|
||||||
|
search_running_node(_, []) ->
|
||||||
|
false;
|
||||||
|
search_running_node(SNode, [Node | Nodes]) ->
|
||||||
|
case atom_to_list(Node) of
|
||||||
|
SNode ->
|
||||||
|
Node;
|
||||||
|
_ ->
|
||||||
|
search_running_node(SNode, Nodes)
|
||||||
|
end.
|
||||||
|
|
||||||
|
45
src/mod_time.erl
Normal file
45
src/mod_time.erl
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% File : mod_time.erl
|
||||||
|
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
%%% Purpose :
|
||||||
|
%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
%%% Id : $Id$
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(mod_time).
|
||||||
|
-author('alexey@sevcom.net').
|
||||||
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
|
-export([start/0,
|
||||||
|
process_local_iq/3]).
|
||||||
|
|
||||||
|
-include("ejabberd.hrl").
|
||||||
|
-include("namespaces.hrl").
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
start() ->
|
||||||
|
ejabberd_local:register_iq_handler(?NS_TIME,
|
||||||
|
?MODULE, process_local_iq).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||||
|
case Type of
|
||||||
|
set ->
|
||||||
|
{iq, ID, error, XMLNS,
|
||||||
|
[SubEl, {xmlelement, "error",
|
||||||
|
[{"code", "405"}],
|
||||||
|
[{xmlcdata, "Not Allowed"}]}]};
|
||||||
|
get ->
|
||||||
|
UTC = jlib:timestamp_to_iso(calendar:universal_time()),
|
||||||
|
{iq, ID, result, XMLNS,
|
||||||
|
[{xmlelement, "query",
|
||||||
|
[{"xmlns", ?NS_TIME}],
|
||||||
|
[{xmlelement, "utc", [],
|
||||||
|
[{xmlcdata, UTC}]}
|
||||||
|
]}]}
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
64
src/mod_version.erl
Normal file
64
src/mod_version.erl
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% File : mod_version.erl
|
||||||
|
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
%%% Purpose :
|
||||||
|
%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
%%% Id : $Id$
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(mod_version).
|
||||||
|
-author('alexey@sevcom.net').
|
||||||
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
|
-export([start/0,
|
||||||
|
process_local_iq/3]).
|
||||||
|
|
||||||
|
-include("ejabberd.hrl").
|
||||||
|
-include("namespaces.hrl").
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
start() ->
|
||||||
|
ejabberd_local:register_iq_handler(?NS_VERSION,
|
||||||
|
?MODULE, process_local_iq).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||||
|
case Type of
|
||||||
|
set ->
|
||||||
|
{iq, ID, error, XMLNS,
|
||||||
|
[SubEl, {xmlelement, "error",
|
||||||
|
[{"code", "405"}],
|
||||||
|
[{xmlcdata, "Not Allowed"}]}]};
|
||||||
|
get ->
|
||||||
|
OSType = case os:type() of
|
||||||
|
{Osfamily, Osname} ->
|
||||||
|
atom_to_list(Osfamily) ++ "/" ++
|
||||||
|
atom_to_list(Osname);
|
||||||
|
Osfamily ->
|
||||||
|
atom_to_list(Osfamily)
|
||||||
|
end,
|
||||||
|
OSVersion = case os:version() of
|
||||||
|
{Major, Minor, Release} ->
|
||||||
|
lists:flatten(
|
||||||
|
io_lib:format("~w.~w.~w",
|
||||||
|
[Major, Minor, Release]));
|
||||||
|
VersionString ->
|
||||||
|
VersionString
|
||||||
|
end,
|
||||||
|
OS = OSType ++ " " ++ OSVersion,
|
||||||
|
{iq, ID, result, XMLNS,
|
||||||
|
[{xmlelement, "query",
|
||||||
|
[{"xmlns", ?NS_VERSION}],
|
||||||
|
[{xmlelement, "name", [],
|
||||||
|
[{xmlcdata, "ejabberd"}]},
|
||||||
|
{xmlelement, "version", [],
|
||||||
|
[{xmlcdata, ?VERSION}]},
|
||||||
|
{xmlelement, "os", [],
|
||||||
|
[{xmlcdata, OS}]}
|
||||||
|
]}]}
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
@ -13,6 +13,8 @@
|
|||||||
-define(NS_SEARCH, "jabber:iq:search").
|
-define(NS_SEARCH, "jabber:iq:search").
|
||||||
-define(NS_ROSTER, "jabber:iq:roster").
|
-define(NS_ROSTER, "jabber:iq:roster").
|
||||||
-define(NS_PRIVATE, "jabber:iq:private").
|
-define(NS_PRIVATE, "jabber:iq:private").
|
||||||
|
-define(NS_VERSION, "jabber:iq:version").
|
||||||
|
-define(NS_TIME, "jabber:iq:time").
|
||||||
-define(NS_XDATA, "jabber:x:data").
|
-define(NS_XDATA, "jabber:x:data").
|
||||||
-define(NS_DELAY, "jabber:x:delay").
|
-define(NS_DELAY, "jabber:x:delay").
|
||||||
-define(NS_EVENT, "jabber:x:event").
|
-define(NS_EVENT, "jabber:x:event").
|
||||||
|
Loading…
Reference in New Issue
Block a user