+2003-07-20 Alexey Shchepin <alexey@sevcom.net>
+
+ * (all): Reorganized supervision tree
+
+2003-07-19 Alexey Shchepin <alexey@sevcom.net>
+
+ * src/mod_register.erl: Bugfix
+
2003-07-14 Alexey Shchepin <alexey@sevcom.net>
* src/ejabberd_s2s_out.erl: Close connection after key
[{description, "ejabberd"},
{vsn, "0.1-alpha"},
{modules, [acl,
+ configure,
+ cyrsasl,
+ cyrsasl_digest,
+ cyrsasl_plain,
ejabberd,
+ ejabberd_app,
ejabberd_auth,
ejabberd_c2s,
ejabberd_config,
ejabberd_s2s_out,
ejabberd_service,
ejabberd_sm,
+ ejabberd_sup,
+ ejabberd_tmp_sup,
+ gen_iq_handler,
+ gen_mod,
+ jd2ejd,
jlib,
mod_configure,
mod_disco,
mod_version,
randoms,
sha,
+ shaper,
translate,
xml,
xml_stream
]},
{registered, [ejabberd,
+ ejabberd_sup,
ejabberd_auth,
ejabberd_router,
ejabberd_sm,
ejabberd_s2s,
ejabberd_local,
+ ejabberd_listeners,
+ ejabberd_iq_sup,
+ ejabberd_service_sup,
+ ejabberd_s2s_out_sup,
+ ejabberd_s2s_in_sup,
+ ejabberd_c2s_sup,
ejabberd_mod_roster,
- ejabberd_listeners
+ ejabberd_mod_echo,
+ ejabberd_mod_pubsub,
+ ejabberd_mod_irc,
+ ejabberd_mod_muc,
+ ejabberd_offline,
+ random_generator
]},
{applications, [kernel, stdlib]},
{env, []},
-export([start/0, stop/0]).
start() ->
- %application:start(mnesia),
application:start(ejabberd).
stop() ->
-include("ejabberd.hrl").
start(normal, Args) ->
+ application:start(sasl),
randoms:start(),
db_init(),
sha:start(),
ejabberd_config:start(),
ejabberd_auth:start(),
cyrsasl:start(),
+ % Profiling
+ %eprof:start(),
+ %eprof:profile([self()]),
Sup = ejabberd_sup:start_link(),
start(),
load_modules(),
ok.
start() ->
- spawn(?MODULE, init, []).
+ spawn_link(?MODULE, init, []).
init() ->
register(ejabberd, self()),
- % Profiling
- %eprof:start(),
- %eprof:profile([self()]),
%erlang:system_flag(fullsweep_after, 0),
error_logger:logfile({open, ?LOG_PATH}),
timer:apply_interval(3600000, ?MODULE, dump_ports, []),
-behaviour(gen_fsm).
%% External exports
--export([start_link/2, receiver/4, send_text/2, send_element/2]).
+-export([start/2,
+ start_link/2,
+ receiver/4,
+ send_text/2,
+ send_element/2]).
%% gen_fsm callbacks
-export([init/1,
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
+start(SockData, Opts) ->
+ supervisor:start_child(ejabberd_c2s_sup, [SockData, Opts]).
+
start_link(SockData, Opts) ->
gen_fsm:start_link(ejabberd_c2s, [SockData, Opts], ?FSMOPTS).
session_established({xmlstreamelement, El}, StateData) ->
{xmlelement, Name, Attrs, Els} = El,
+ User = StateData#state.user,
Server = StateData#state.server,
- FromJID = {StateData#state.user,
+ FromJID = {User,
Server,
StateData#state.resource},
To = xml:get_attr_s("to", Attrs),
ToJID = case To of
"" ->
- {"", Server, ""};
+ {User, Server, ""};
_ ->
jlib:string_to_jid(To)
end,
case Name of
"presence" ->
case ToJID of
- {"", Server, ""} ->
+ {User, Server, ""} ->
?DEBUG("presence_update(~p,~n\t~p,~n\t~p)",
[FromJID, El, StateData]),
presence_update(FromJID, El, StateData);
permanent,
brutal_kill,
worker,
- [Module]}
+ [?MODULE]}
end, Ls)}}
end.
accept(ListenSocket, Module, Opts) ->
case gen_tcp:accept(ListenSocket) of
{ok, Socket} ->
- {ok, Pid} = apply(Module, start_link, [{gen_tcp, Socket}, Opts]),
+ {ok, Pid} = Module:start({gen_tcp, Socket}, Opts),
+ %{ok, Pid} =
+ % supervisor:start_child(
+ % ejabberd_tmp_sup,
+ % {{Module, Socket},
+ % {Module, start_link, [{gen_tcp, Socket}, Opts]},
+ % transient,
+ % brutal_kill,
+ % worker,
+ % [Module]}),
gen_tcp:controlling_process(Socket, Pid),
accept(ListenSocket, Module, Opts)
end.
ok;
{atomic, new} ->
?DEBUG("starting new s2s connection~n", []),
- Pid = ejabberd_s2s_out:start_link(MyServer, Server, {new, Key}),
+ {ok, Pid} = ejabberd_s2s_out:start(MyServer, Server, {new, Key}),
mnesia:transaction(fun() ->
mnesia:write(#local_s2s{fromto = FromTo,
pid = Pid})
-behaviour(gen_fsm).
%% External exports
--export([start_link/2, receiver/2, send_text/2, send_element/2]).
+-export([start/2, start_link/2, receiver/2, send_text/2, send_element/2]).
%% gen_fsm callbacks
-export([init/1,
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
+start(SockData, Opts) ->
+ supervisor:start_child(ejabberd_s2s_in_sup, [SockData, Opts]).
+
start_link(SockData, Opts) ->
gen_fsm:start_link(ejabberd_s2s_in, [SockData], ?FSMOPTS).
?INFO_MSG("GET KEY: ~p", [{To, From, Id, Key}]),
case lists:member(To, ejabberd_router:dirty_get_all_domains()) of
true ->
- ejabberd_s2s_out:start_link(To, From,
- {verify, self(), Key}),
+ ejabberd_s2s_out:start(To, From,
+ {verify, self(), Key}),
{next_state,
wait_for_verification,
StateData#state{myname = To,
-behaviour(gen_fsm).
%% External exports
--export([start_link/3, send_text/2, send_element/2]).
+-export([start/3, start_link/3, send_text/2, send_element/2]).
%% gen_fsm callbacks
-export([init/1,
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
+start(From, Host, Type) ->
+ supervisor:start_child(ejabberd_s2s_out_sup, [From, Host, Type]).
+
start_link(From, Host, Type) ->
- {ok, Pid} = gen_fsm:start_link(ejabberd_s2s_out, [From, Host, Type],
- ?FSMOPTS),
- Pid.
+ gen_fsm:start_link(ejabberd_s2s_out, [From, Host, Type], ?FSMOPTS).
%%%----------------------------------------------------------------------
%%% Callback functions from gen_fsm
-behaviour(gen_fsm).
%% External exports
--export([start_link/2, receiver/2, send_text/2, send_element/2]).
+-export([start/2, start_link/2, receiver/2, send_text/2, send_element/2]).
%% gen_fsm callbacks
-export([init/1,
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
+start(SockData, Opts) ->
+ supervisor:start_child(ejabberd_service_sup, [SockData, Opts]).
+
start_link(SockData, Opts) ->
gen_fsm:start_link(ejabberd_service, [SockData, Opts], ?FSMOPTS).
Listener = {ejabberd_listener,
{ejabberd_listener, start_link, []},
permanent,
- brutal_kill,
+ infinity,
supervisor,
[ejabberd_listener]},
- {ok, {{one_for_one, 10, 1}, [Router, SM, S2S, Local, Listener]}}.
+ C2SSupervisor =
+ {ejabberd_c2s_sup,
+ {ejabberd_tmp_sup, start_link, [ejabberd_c2s_sup, ejabberd_c2s]},
+ permanent,
+ infinity,
+ supervisor,
+ [ejabberd_tmp_sup]},
+ S2SInSupervisor =
+ {ejabberd_s2s_in_sup,
+ {ejabberd_tmp_sup, start_link,
+ [ejabberd_s2s_in_sup, ejabberd_s2s_in]},
+ permanent,
+ infinity,
+ supervisor,
+ [ejabberd_tmp_sup]},
+ S2SOutSupervisor =
+ {ejabberd_s2s_out_sup,
+ {ejabberd_tmp_sup, start_link,
+ [ejabberd_s2s_out_sup, ejabberd_s2s_out]},
+ permanent,
+ infinity,
+ supervisor,
+ [ejabberd_tmp_sup]},
+ ServiceSupervisor =
+ {ejabberd_service_sup,
+ {ejabberd_tmp_sup, start_link,
+ [ejabberd_service_sup, ejabberd_service]},
+ permanent,
+ infinity,
+ supervisor,
+ [ejabberd_tmp_sup]},
+ IQSupervisor =
+ {ejabberd_iq_sup,
+ {ejabberd_tmp_sup, start_link,
+ [ejabberd_iq_sup, gen_iq_handler]},
+ permanent,
+ infinity,
+ supervisor,
+ [ejabberd_tmp_sup]},
+ {ok, {{one_for_one, 10, 1},
+ [Router, SM, S2S, Local,
+ C2SSupervisor,
+ S2SInSupervisor,
+ S2SOutSupervisor,
+ ServiceSupervisor,
+ IQSupervisor,
+ Listener]}}.
--- /dev/null
+%%%----------------------------------------------------------------------
+%%% File : ejabberd_tmp_sup.erl
+%%% Author : Alexey Shchepin <alexey@sevcom.net>
+%%% Purpose : Supervisor for temporary processess
+%%% Created : 18 Jul 2003 by Alexey Shchepin <alexey@sevcom.net>
+%%% Id : $Id$
+%%%----------------------------------------------------------------------
+
+-module(ejabberd_tmp_sup).
+-author('alexey@sevcom.net').
+-vsn('$Revision$ ').
+
+-export([start_link/2, init/1]).
+
+start_link(Name, Module) ->
+ supervisor:start_link({local, Name}, ?MODULE, Module).
+
+
+init(Module) ->
+ {ok, {{simple_one_for_one, 10, 1},
+ [{undefined, {Module, start_link, []},
+ temporary, brutal_kill, worker, [Module]}]}}.
-vsn('$Revision$ ').
-export([start/0,
+ start_link/2,
add_iq_handler/5,
remove_iq_handler/2,
stop_iq_handler/3,
no_queue ->
Component:register_iq_handler(NS, Module, Function, no_queue);
one_queue ->
- Pid = spawn(?MODULE, queue_init, [Module, Function]),
+ {ok, Pid} = supervisor:start_child(ejabberd_iq_sup,
+ [Module, Function]),
Component:register_iq_handler(NS, Module, Function,
{one_queue, Pid});
parallel ->
end
end.
+start_link(Module, Function) ->
+ {ok, proc_lib:spawn_link(?MODULE, queue_init, [Module, Function])}.
+
queue_init(Module, Function) ->
queue_loop(Module, Function).
% [?LOWER(Char) || Char <- S].
% Not tail-recursive but it seems works faster than variants above
-tolower([C | Cs]) when C >= $A, C =< $Z ->
- [C + 32 | tolower(Cs)];
tolower([C | Cs]) ->
- [C | tolower(Cs)];
+ if
+ C >= $A, C =< $Z ->
+ [C + 32 | tolower(Cs)];
+ true ->
+ [C | tolower(Cs)]
+ end;
tolower([]) ->
[].
+%tolower([C | Cs]) when C >= $A, C =< $Z ->
+% [C + 32 | tolower(Cs)];
+%tolower([C | Cs]) ->
+% [C | tolower(Cs)];
+%tolower([]) ->
+% [].
+
+
jid_tolower({U, S, R}) ->
{tolower(U), tolower(S), R}.
mnesia:create_table(private_storage,
[{disc_only_copies, [node()]},
{attributes, record_info(fields, private_storage)}]),
- gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_PRIVATE,
+ gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_PRIVATE,
?MODULE, process_local_iq, IQDisc).
stop() ->
-behaviour(gen_mod).
-export([start/1,
- init/2,
+ init/3,
+ loop/2,
stop/0,
- % TODO: remove
- create_new_node/3,
- publish_item/5,
- delete_item/4]).
+ system_continue/3,
+ system_terminate/4,
+ system_code_change/4]).
-include("ejabberd.hrl").
-include("jlib.hrl").
mnesia:add_table_index(pubsub_node, parent),
Host = gen_mod:get_opt(host, Opts, "pubsub." ++ ?MYNAME),
ServedHosts = gen_mod:get_opt(served_hosts, Opts, [?MYNAME]),
- register(ejabberd_mod_pubsub, spawn(?MODULE, init, [Host, ServedHosts])).
+ register(ejabberd_mod_pubsub,
+ proc_lib:spawn_link(?MODULE, init, [Host, ServedHosts, self()])).
-init(Host, ServedHosts) ->
+init(Host, ServedHosts, Parent) ->
ejabberd_router:register_route(Host),
create_new_node(Host, ["pubsub"], {"", Host, ""}),
create_new_node(Host, ["pubsub", "nodes"], {"", Host, ""}),
lists:foreach(fun(H) ->
create_new_node(Host, ["home", H], {"", Host, ""})
end, ServedHosts),
- loop(Host).
+ loop(Host, Parent).
-loop(Host) ->
+loop(Host, Parent) ->
receive
{route, From, To, Packet} ->
case catch do_route(Host, From, To, Packet) of
_ ->
ok
end,
- loop(Host);
+ loop(Host, Parent);
{room_destroyed, Room} ->
ets:delete(muc_online_room, Room),
- loop(Host);
+ loop(Host, Parent);
stop ->
ejabberd_router:unregister_global_route(Host),
ok;
reload ->
- ?MODULE:loop(Host);
+ ?MODULE:loop(Host, Parent);
+ {system, From, Request} ->
+ sys:handle_system_msg(Request, From, Parent, ?MODULE, [], Host);
_ ->
- loop(Host)
+ loop(Host, Parent)
end.
create_new_node(Host, Node, Owner) ->
case Node of
[] ->
- {error, ?ERR_CONFLICT};
+ {LOU, LOS, _} = jlib:jid_tolower(Owner),
+ NewNode = ["home", LOS, LOU, randoms:get_string()],
+ create_new_node(Host, NewNode, Owner);
_ ->
LOwner = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
Parent = lists:sublist(Node, length(Node) - 1),
{atomic, ok} ->
Lang = "",
broadcast_publish_item(
- Host, ["pubsub", "nodes"], "",
+ Host, ["pubsub", "nodes"], node_to_string(Node),
[{xmlelement, "x",
- [{"xmlns", ?NS_PUBSUB_EVENT},
+ [{"xmlns", ?NS_XDATA},
{"type", "result"}],
[?XFIELD("hidden", "", "FORM_TYPE",
?NS_PUBSUB_NMI),
?XFIELD("jid-single", "Node Creator",
"creator",
jlib:jid_to_string(LOwner))]}]),
- {result, []};
+ {result,
+ [{xmlelement, "pubsub",
+ [{"xmlns", ?NS_PUBSUB}],
+ [{xmlelement, "create",
+ [{"node", node_to_string(Node)}], []}]}]};
{atomic, {error, _} = Error} ->
Error;
_ ->
Error;
{atomic, {removed, Removed}} ->
broadcast_removed_node(Host, Removed),
+ Lang = "",
+ broadcast_retract_item(
+ Host, ["pubsub", "nodes"], node_to_string(Node)),
{result, []};
_ ->
{error, ?ERR_INTERNAL_SERVER_ERROR}
{xmlelement, "message", [],
[{xmlelement, "x",
[{"xmlns", ?NS_PUBSUB_EVENT}],
- [{xmlelement, "retract",
+ [{xmlelement, "items",
[{"node", node_to_string(Node)}],
- []}]}]},
+ [{xmlelement, "retract",
+ ItemAttrs, []}]}]}]},
ejabberd_router:route({"", Host, ""},
JID, Stanza);
true ->
end, ok, Entities)
end, Removed).
+
+
+system_continue(Parent, _, State) ->
+ loop(State, Parent).
+
+system_terminate(Reason, Parent, _, State) ->
+ exit(Reason).
+
+system_code_change(State, _Mod, Ver, _Extra) ->
+ {ok, State}.
[SubEl, ?ERR_BAD_REQUEST]}
end
end;
- {iq, ID, error, XMLNS,
- [SubEl, ?ERR_FEATURE_NOT_IMPLEMENTED]};
(UTag /= false) and (PTag /= false) ->
User = xml:get_tag_cdata(UTag),
Password = xml:get_tag_cdata(PTag),
{iq, ID, error, XMLNS,
[SubEl, Error]}
end
- end
+ end;
+ true ->
+ {iq, ID, error, XMLNS,
+ [SubEl, ?ERR_BAD_REQUEST]}
end;
get ->
{iq, ID, result, XMLNS, [{xmlelement,
mnesia:create_table(roster,[{disc_copies, [node()]},
{attributes, record_info(fields, roster)}]),
mnesia:add_table_index(roster, user),
- gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_ROSTER,
+ gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_ROSTER,
?MODULE, process_local_iq, IQDisc).
process_local_iq(From, To, {iq, _, Type, _, _} = IQ) ->
ok.
load_dir(Dir) ->
- {ok, Files} = file:list_dir(Dir),
- MsgFiles = lists:filter(
- fun(FN) ->
- case string:len(FN) > 4 of
- true ->
- string:substr(FN,
- string:len(FN) - 3) == ".msg";
- _ ->
- false
- end
- end, Files),
- lists:foreach(
- fun(FN) ->
- load_file(string:substr(FN, 1, string:len(FN) - 4),
- Dir ++ "/" ++ FN)
- end, MsgFiles),
- ok.
+ case file:list_dir(Dir) of
+ {ok, Files} ->
+ MsgFiles = lists:filter(
+ fun(FN) ->
+ case string:len(FN) > 4 of
+ true ->
+ string:substr(FN,
+ string:len(FN) - 3) == ".msg";
+ _ ->
+ false
+ end
+ end, Files),
+ lists:foreach(
+ fun(FN) ->
+ load_file(string:substr(FN, 1, string:len(FN) - 4),
+ Dir ++ "/" ++ FN)
+ end, MsgFiles),
+ ok;
+ {error, Reason} ->
+ ?ERROR_MSG("~p", [Reason])
+ end.
load_file(Lang, File) ->
case file:consult(File) of
-%crypt(S) ->
-% lists:reverse(crypt(S, "")).
-%
-%crypt([$& | S], R) ->
-% crypt(S, [$;, $p, $m, $a, $& | R]);
-%crypt([$< | S], R) ->
-% crypt(S, [$;, $t, $l, $& | R]);
-%crypt([$> | S], R) ->
-% crypt(S, [$;, $t, $g, $& | R]);
-%crypt([$" | S], R) ->
-% crypt(S, [$;, $t, $o, $u, $q, $& | R]);
-%crypt([$' | S], R) ->
-% crypt(S, [$;, $s, $o, $p, $a, $& | R]);
-%crypt([C | S], R) ->
-% crypt(S, [C | R]);
-%crypt([], R) ->
-% R.
+crypt(S) ->
+ lists:reverse(crypt(S, "")).
+
+crypt([$& | S], R) ->
+ crypt(S, [$;, $p, $m, $a, $& | R]);
+crypt([$< | S], R) ->
+ crypt(S, [$;, $t, $l, $& | R]);
+crypt([$> | S], R) ->
+ crypt(S, [$;, $t, $g, $& | R]);
+crypt([$" | S], R) ->
+ crypt(S, [$;, $t, $o, $u, $q, $& | R]);
+crypt([$' | S], R) ->
+ crypt(S, [$;, $s, $o, $p, $a, $& | R]);
+crypt([C | S], R) ->
+ crypt(S, [C | R]);
+crypt([], R) ->
+ R.
%crypt1(S) ->
% lists:flatten([case C of
% _ -> C
% end || C <- S]).
-% Not tail-recursive but it seems works faster than variants above
-crypt([$& | S]) ->
- [$&, $a, $m, $p, $; | crypt(S)];
-crypt([$< | S]) ->
- [$&, $l, $t, $; | crypt(S)];
-crypt([$> | S]) ->
- [$&, $g, $t, $; | crypt(S)];
-crypt([$" | S]) ->
- [$&, $q, $u, $o, $t, $; | crypt(S)];
-crypt([$' | S]) ->
- [$&, $a, $p, $o, $s, $; | crypt(S)];
-crypt([C | S]) ->
- [C | crypt(S)];
-crypt([]) ->
- [].
+%crypt([$& | S]) ->
+% [$&, $a, $m, $p, $; | crypt(S)];
+%crypt([$< | S]) ->
+% [$&, $l, $t, $; | crypt(S)];
+%crypt([$> | S]) ->
+% [$&, $g, $t, $; | crypt(S)];
+%crypt([$" | S]) ->
+% [$&, $q, $u, $o, $t, $; | crypt(S)];
+%crypt([$' | S]) ->
+% [$&, $a, $p, $o, $s, $; | crypt(S)];
+%crypt([C | S]) ->
+% [C | crypt(S)];
+%crypt([]) ->
+% [].