*** empty log message ***

SVN Revision: 43
This commit is contained in:
Alexey Shchepin 2003-01-18 19:42:48 +00:00
parent c060093e84
commit 942fbb9fae
14 changed files with 404 additions and 134 deletions

51
src/acl.erl Normal file
View 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)).

View File

@ -1,5 +1,12 @@
% $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"}.

View File

@ -19,7 +19,7 @@ start() ->
init() ->
register(ejabberd, self()),
erlang:system_flag(fullsweep_after, 0),
%erlang:system_flag(fullsweep_after, 0),
error_logger:logfile({open, ?ERROR_LOG_PATH}),
randoms:start(),
ok = erl_ddll:load_driver(".", expat_erl),
@ -27,6 +27,7 @@ init() ->
db_init(),
sha:start(),
translate:start(),
acl:start(),
ejabberd_config:start(),
ejabberd_auth:start(),
ejabberd_router:start(),

View File

@ -6,6 +6,8 @@
%%% Id : $Id$
%%%----------------------------------------------------------------------
-define(VERSION, "0.0.1-alpha").
%-define(ejabberd_debug, true).
%-define(DBGFSM, true).

View File

@ -22,13 +22,19 @@ start() ->
load_file(File) ->
case file:consult(File) of
{ok, Terms} ->
lists:foreach(fun({Opt, Val}) ->
ets:insert(ejabberd_config, {Opt, Val})
end, Terms);
lists:foreach(fun process_term/1, Terms);
{error, Reason} ->
exit(file:format_error(Reason))
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) ->
case ets:lookup(ejabberd_config, Opt) of

View File

@ -28,6 +28,8 @@ start() ->
mod_offline:start(),
mod_echo:start(),
mod_private:start(),
mod_time:start(),
mod_version:start(),
ok.
init() ->
@ -60,10 +62,8 @@ do_route(State, From, To, Packet) ->
"message" ->
ok;
"presence" ->
% TODO
ok;
_ ->
% DROP
ok
end;
{"", _, _} ->

View File

@ -101,9 +101,10 @@ loop() ->
do_route(From, To, Packet) ->
?DEBUG("route~n\tfrom ~p~n\tto ~p~n\tpacket ~p~n", [From, To, Packet]),
{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};
[R] ->

View File

@ -15,6 +15,7 @@
set_presence/3,
unset_presence/2,
dirty_get_sessions_list/0,
dirty_get_my_sessions_list/0,
register_iq_handler/3]).
-include_lib("mnemosyne/include/mnemosyne.hrl").
@ -250,8 +251,8 @@ do_route(From, To, Packet) ->
ok
end;
_ ->
UR = {User, Resource},
Sess = mnesia:dirty_read({session, UR}),
LUR = {jlib:tolower(User), Resource},
Sess = mnesia:dirty_read({session, LUR}),
case Sess of
[] ->
if
@ -261,7 +262,7 @@ do_route(From, To, Packet) ->
?DEBUG("packet droped~n", [])
end;
[Ses] ->
case mnesia:dirty_read({mysession, UR}) of
case mnesia:dirty_read({mysession, LUR}) of
[] ->
Node = Ses#session.node,
?DEBUG("sending to node ~p~n", [Node]),
@ -344,6 +345,9 @@ get_user_present_resources(User) ->
dirty_get_sessions_list() ->
mnesia:dirty_all_keys(session).
dirty_get_my_sessions_list() ->
mnesia:dirty_all_keys(mysession).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View File

@ -27,6 +27,7 @@
is_iq_request_type/1,
iq_to_xml/1,
parse_xdata_submit/1,
timestamp_to_iso/1,
timestamp_to_xml/1]).
-include("namespaces.hrl").
@ -293,6 +294,11 @@ 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}}) ->
{xmlelement, "x",
[{"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",
[Year, Month, Day, Hour, Minute, Second]))}],
[]}.

View File

@ -53,55 +53,19 @@ process_local_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
[{"code", "405"}],
[{xmlcdata, "Not Allowed"}]}]};
get ->
case string:tokens(xml:get_tag_attr_s("node", SubEl), "/") of
[] ->
Domains =
lists:map(fun domain_to_xml/1,
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"] ->
Node = string:tokens(xml:get_tag_attr_s("node", SubEl), "/"),
case get_local_items(Node, jlib:jid_to_string(To), Lang) of
{result, Res} ->
{iq, ID, result, XMLNS,
[{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
get_online_users()
Res
}]};
["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)
}]};
_ ->
{error, Code, Desc} ->
{iq, ID, error, XMLNS,
[SubEl, {xmlelement, "error",
[{"code", "501"}],
[{xmlcdata, "Not Implemented"}]}]}
[{"code", Code}],
[{xmlcdata, Desc}]}]}
end
end.
@ -129,6 +93,19 @@ process_local_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
["online users"] -> ?EMPTY_INFO_RESULT;
["all users"] -> ?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,
[SubEl, {xmlelement, "error",
@ -145,6 +122,51 @@ domain_to_xml(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() ->
case catch ejabberd_sm:dirty_get_sessions_list() of
{'EXIT', Reason} ->
@ -208,6 +230,44 @@ get_outgoing_s2s(Lang, To) ->
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}) ->
{User, _, _} = To,
case Type of

View File

@ -31,49 +31,16 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
Node = string:tokens(xml:get_tag_attr_s("node", SubEl), "/"),
Names = get_names(Els, []),
{T, Res} = get_local_stats(Node, Names),
case T of
result ->
{iq, ID, result, ?NS_STATS, Res};
error ->
{iq, ID, error, ?NS_STATS, [SubEl ++ Res]}
case get_local_stats(Node, Names) of
{result, Res} ->
{iq, ID, result, XMLNS,
[{xmlelement, "query", [{"xmlns", XMLNS}], Res}]};
{error, Code, Desc} ->
{iq, ID, error, XMLNS,
[SubEl, {xmlelement, "error",
[{"code", Code}],
[{xmlcdata, Desc}]}]}
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.
@ -91,31 +58,39 @@ get_names([_ | Els], Res) ->
get_names(Els, Res).
-define(STAT(Name), {xmlelement, "stat", [{"name", Name}], []}).
get_local_stats([], []) ->
{result,
[{xmlelement,
"query",
[{"xmlns", ?NS_STATS}],
[{xmlelement, "stat", [{"name", "time/uptime"}], []},
{xmlelement, "stat", [{"name", "time/cputime"}], []},
{xmlelement, "stat", [{"name", "users/online"}], []},
{xmlelement, "stat", [{"name", "users/total"}], []}
]}]};
[?STAT("users/online"),
?STAT("users/total")
]};
get_local_stats([], Names) ->
{result, lists:map(fun(Name) -> get_local_stat([], Name) end, Names)};
get_local_stats(["running nodes", _], []) ->
{result,
[{xmlelement,
"query",
[{"xmlns", ?NS_STATS}],
lists:map(fun(Name) -> get_local_stat([], Name) end, Names)
}]};
[?STAT("time/uptime"),
?STAT("time/cputime"),
?STAT("users/online")
]};
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(_, _) ->
{error,
[{xmlelement, "error",
[{"code", "501"}],
[{xmlcdata, "Not Implemented"}]}]}.
{error, "501", "Not Implemented"}.
-define(STAT(Val, Unit),
-define(STATVAL(Val, Unit),
{xmlelement, "stat",
[{"name", Name},
{"units", Unit},
@ -130,25 +105,70 @@ get_local_stats(_, _) ->
[{xmlcdata, Desc}]}]}).
get_local_stat([], Name) when Name == "time/uptime" ->
?STAT(io_lib:format("~.3f", [element(1, statistics(wall_clock))/1000]),
"seconds");
get_local_stat([], Name) when Name == "time/cputime" ->
?STAT(io_lib:format("~.3f", [element(1, statistics(runtime))/1000]),
"seconds");
%get_local_stat([], Name) when Name == "time/uptime" ->
% ?STATVAL(io_lib:format("~.3f", [element(1, statistics(wall_clock))/1000]),
% "seconds");
%get_local_stat([], Name) when Name == "time/cputime" ->
% ?STATVAL(io_lib:format("~.3f", [element(1, statistics(runtime))/1000]),
% "seconds");
get_local_stat([], Name) when Name == "users/online" ->
case catch ejabberd_sm:dirty_get_sessions_list() of
{'EXIT', Reason} ->
?STATERR("500", "Internal Server Error");
Users ->
?STAT(integer_to_list(length(Users)), "users")
?STATVAL(integer_to_list(length(Users)), "users")
end;
get_local_stat([], Name) when Name == "users/total" ->
case catch ejabberd_auth:dirty_get_registered_users() of
{'EXIT', Reason} ->
?STATERR("500", "Internal Server Error");
Users ->
?STAT(integer_to_list(length(Users)), "users")
?STATVAL(integer_to_list(length(Users)), "users")
end;
get_local_stat(_, Name) ->
?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
View 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
View 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.

View File

@ -6,16 +6,18 @@
%%%----------------------------------------------------------------------
-define(NS_DISCO_ITEMS, "http://jabber.org/protocol/disco#items").
-define(NS_DISCO_INFO, "http://jabber.org/protocol/disco#info").
-define(NS_VCARD, "vcard-temp").
-define(NS_AUTH, "jabber:iq:auth").
-define(NS_REGISTER, "jabber:iq:register").
-define(NS_SEARCH, "jabber:iq:search").
-define(NS_ROSTER, "jabber:iq:roster").
-define(NS_PRIVATE, "jabber:iq:private").
-define(NS_XDATA, "jabber:x:data").
-define(NS_DELAY, "jabber:x:delay").
-define(NS_EVENT, "jabber:x:event").
-define(NS_STATS, "http://jabber.org/protocol/stats").
-define(NS_DISCO_INFO, "http://jabber.org/protocol/disco#info").
-define(NS_VCARD, "vcard-temp").
-define(NS_AUTH, "jabber:iq:auth").
-define(NS_REGISTER, "jabber:iq:register").
-define(NS_SEARCH, "jabber:iq:search").
-define(NS_ROSTER, "jabber:iq:roster").
-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_DELAY, "jabber:x:delay").
-define(NS_EVENT, "jabber:x:event").
-define(NS_STATS, "http://jabber.org/protocol/stats").