mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
* src/mod_pubsub/mod_pubsub.erl: Updated to use gen_server
behaviour and ejabberd supervision tree * src/mod_muc/mod_muc.erl: Added a supervisor for conference room processes * src/mod_muc/mod_muc_room.erl: Likewise SVN Revision: 496
This commit is contained in:
parent
50f44530d2
commit
971001e7aa
13
ChangeLog
13
ChangeLog
@ -1,3 +1,14 @@
|
|||||||
|
2006-02-02 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
|
* src/mod_pubsub/mod_pubsub.erl: Updated to use gen_server
|
||||||
|
behaviour and ejabberd supervision tree
|
||||||
|
|
||||||
|
2006-02-01 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
|
* src/mod_muc/mod_muc.erl: Added a supervisor for conference room
|
||||||
|
processes
|
||||||
|
* src/mod_muc/mod_muc_room.erl: Likewise
|
||||||
|
|
||||||
2006-01-29 Alexey Shchepin <alexey@sevcom.net>
|
2006-01-29 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
* src/odbc/pg.sql: Fixed syntax error
|
* src/odbc/pg.sql: Fixed syntax error
|
||||||
@ -10,7 +21,7 @@
|
|||||||
* src/gen_iq_handler.erl: Likewise
|
* src/gen_iq_handler.erl: Likewise
|
||||||
|
|
||||||
* src/ejabberd_sup.erl: Added supervisor for ejabberd_receiver
|
* src/ejabberd_sup.erl: Added supervisor for ejabberd_receiver
|
||||||
* src/ejabberd_receiver.erl: Updating
|
* src/ejabberd_receiver.erl: Updated
|
||||||
|
|
||||||
2006-01-27 Alexey Shchepin <alexey@sevcom.net>
|
2006-01-27 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
|
123
src/mod_echo.erl
123
src/mod_echo.erl
@ -10,38 +10,117 @@
|
|||||||
-author('alexey@sevcom.net').
|
-author('alexey@sevcom.net').
|
||||||
-vsn('$Revision$ ').
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
|
-behaviour(gen_server).
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, init/1, stop/1]).
|
%% API
|
||||||
|
-export([start_link/2, start/2, stop/1]).
|
||||||
|
|
||||||
|
%% gen_server callbacks
|
||||||
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||||
|
terminate/2, code_change/3]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
|
|
||||||
|
-record(state, {host}).
|
||||||
|
|
||||||
-define(PROCNAME, ejabberd_mod_echo).
|
-define(PROCNAME, ejabberd_mod_echo).
|
||||||
|
|
||||||
|
%%====================================================================
|
||||||
|
%% API
|
||||||
|
%%====================================================================
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
|
||||||
|
%% Description: Starts the server
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
start_link(Host, Opts) ->
|
||||||
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
|
gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []).
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
MyHost = gen_mod:get_opt(host, Opts, "echo." ++ Host),
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
ChildSpec =
|
||||||
spawn(?MODULE, init, [MyHost])).
|
{Proc,
|
||||||
|
{?MODULE, start_link, [Host, Opts]},
|
||||||
init(Host) ->
|
temporary,
|
||||||
ejabberd_router:register_route(Host),
|
1000,
|
||||||
loop(Host).
|
worker,
|
||||||
|
[?MODULE]},
|
||||||
loop(Host) ->
|
supervisor:start_child(ejabberd_sup, ChildSpec).
|
||||||
receive
|
|
||||||
{route, From, To, Packet} ->
|
|
||||||
ejabberd_router:route(To, From, Packet),
|
|
||||||
loop(Host);
|
|
||||||
stop ->
|
|
||||||
ejabberd_router:unregister_route(Host),
|
|
||||||
ok;
|
|
||||||
_ ->
|
|
||||||
loop(Host)
|
|
||||||
end.
|
|
||||||
|
|
||||||
stop(Host) ->
|
stop(Host) ->
|
||||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
Proc ! stop,
|
gen_server:call(Proc, stop),
|
||||||
{wait, Proc}.
|
supervisor:stop_child(ejabberd_sup, Proc).
|
||||||
|
|
||||||
|
%%====================================================================
|
||||||
|
%% gen_server callbacks
|
||||||
|
%%====================================================================
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Function: init(Args) -> {ok, State} |
|
||||||
|
%% {ok, State, Timeout} |
|
||||||
|
%% ignore |
|
||||||
|
%% {stop, Reason}
|
||||||
|
%% Description: Initiates the server
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
init([Host, Opts]) ->
|
||||||
|
MyHost = gen_mod:get_opt(host, Opts, "echo." ++ Host),
|
||||||
|
ejabberd_router:register_route(MyHost),
|
||||||
|
{ok, #state{host = MyHost}}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
|
||||||
|
%% {reply, Reply, State, Timeout} |
|
||||||
|
%% {noreply, State} |
|
||||||
|
%% {noreply, State, Timeout} |
|
||||||
|
%% {stop, Reason, Reply, State} |
|
||||||
|
%% {stop, Reason, State}
|
||||||
|
%% Description: Handling call messages
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
handle_call(stop, _From, State) ->
|
||||||
|
{stop, normal, ok, State}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Function: handle_cast(Msg, State) -> {noreply, State} |
|
||||||
|
%% {noreply, State, Timeout} |
|
||||||
|
%% {stop, Reason, State}
|
||||||
|
%% Description: Handling cast messages
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
handle_cast(_Msg, State) ->
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Function: handle_info(Info, State) -> {noreply, State} |
|
||||||
|
%% {noreply, State, Timeout} |
|
||||||
|
%% {stop, Reason, State}
|
||||||
|
%% Description: Handling all non call/cast messages
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
handle_info({route, From, To, Packet}, State) ->
|
||||||
|
ejabberd_router:route(To, From, Packet),
|
||||||
|
{noreply, State};
|
||||||
|
handle_info(_Info, State) ->
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Function: terminate(Reason, State) -> void()
|
||||||
|
%% Description: This function is called by a gen_server when it is about to
|
||||||
|
%% terminate. It should be the opposite of Module:init/1 and do any necessary
|
||||||
|
%% cleaning up. When it returns, the gen_server terminates with Reason.
|
||||||
|
%% The return value is ignored.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
terminate(_Reason, State) ->
|
||||||
|
ejabberd_router:unregister_route(State#state.host),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
|
||||||
|
%% Description: Convert process state when code is changed
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
code_change(_OldVsn, State, _Extra) ->
|
||||||
|
{ok, State}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%%% Internal functions
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
@ -10,10 +10,12 @@
|
|||||||
-author('alexey@sevcom.net').
|
-author('alexey@sevcom.net').
|
||||||
-vsn('$Revision$ ').
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
|
-behaviour(gen_server).
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2,
|
%% API
|
||||||
init/3,
|
-export([start_link/2,
|
||||||
|
start/2,
|
||||||
stop/1,
|
stop/1,
|
||||||
room_destroyed/3,
|
room_destroyed/3,
|
||||||
store_room/3,
|
store_room/3,
|
||||||
@ -22,6 +24,10 @@
|
|||||||
process_iq_disco_items/4,
|
process_iq_disco_items/4,
|
||||||
can_use_nick/3]).
|
can_use_nick/3]).
|
||||||
|
|
||||||
|
%% gen_server callbacks
|
||||||
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||||
|
terminate/2, code_change/3]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
|
|
||||||
@ -30,9 +36,106 @@
|
|||||||
-record(muc_online_room, {name_host, pid}).
|
-record(muc_online_room, {name_host, pid}).
|
||||||
-record(muc_registered, {us_host, nick}).
|
-record(muc_registered, {us_host, nick}).
|
||||||
|
|
||||||
|
-record(state, {host, server_host, access}).
|
||||||
|
|
||||||
-define(PROCNAME, ejabberd_mod_muc).
|
-define(PROCNAME, ejabberd_mod_muc).
|
||||||
|
|
||||||
|
%%====================================================================
|
||||||
|
%% API
|
||||||
|
%%====================================================================
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
|
||||||
|
%% Description: Starts the server
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
start_link(Host, Opts) ->
|
||||||
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
|
gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []).
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
|
start_supervisor(Host),
|
||||||
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
|
ChildSpec =
|
||||||
|
{Proc,
|
||||||
|
{?MODULE, start_link, [Host, Opts]},
|
||||||
|
temporary,
|
||||||
|
1000,
|
||||||
|
worker,
|
||||||
|
[?MODULE]},
|
||||||
|
supervisor:start_child(ejabberd_sup, ChildSpec).
|
||||||
|
|
||||||
|
stop(Host) ->
|
||||||
|
stop_supervisor(Host),
|
||||||
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
|
gen_server:call(Proc, stop),
|
||||||
|
supervisor:delete_child(ejabberd_sup, Proc).
|
||||||
|
|
||||||
|
room_destroyed(Host, Room, ServerHost) ->
|
||||||
|
gen_mod:get_module_proc(ServerHost, ?PROCNAME) !
|
||||||
|
{room_destroyed, {Room, Host}},
|
||||||
|
ok.
|
||||||
|
|
||||||
|
store_room(Host, Name, Opts) ->
|
||||||
|
F = fun() ->
|
||||||
|
mnesia:write(#muc_room{name_host = {Name, Host},
|
||||||
|
opts = Opts})
|
||||||
|
end,
|
||||||
|
mnesia:transaction(F).
|
||||||
|
|
||||||
|
restore_room(Host, Name) ->
|
||||||
|
case catch mnesia:dirty_read(muc_room, {Name, Host}) of
|
||||||
|
[#muc_room{opts = Opts}] ->
|
||||||
|
Opts;
|
||||||
|
_ ->
|
||||||
|
error
|
||||||
|
end.
|
||||||
|
|
||||||
|
forget_room(Host, Name) ->
|
||||||
|
F = fun() ->
|
||||||
|
mnesia:delete({muc_room, {Name, Host}})
|
||||||
|
end,
|
||||||
|
mnesia:transaction(F).
|
||||||
|
|
||||||
|
process_iq_disco_items(Host, From, To, #iq{lang = Lang} = IQ) ->
|
||||||
|
Res = IQ#iq{type = result,
|
||||||
|
sub_el = [{xmlelement, "query",
|
||||||
|
[{"xmlns", ?NS_DISCO_ITEMS}],
|
||||||
|
iq_disco_items(Host, From, Lang)}]},
|
||||||
|
ejabberd_router:route(To,
|
||||||
|
From,
|
||||||
|
jlib:iq_to_xml(Res)).
|
||||||
|
|
||||||
|
can_use_nick(_Host, _JID, "") ->
|
||||||
|
false;
|
||||||
|
can_use_nick(Host, JID, Nick) ->
|
||||||
|
{LUser, LServer, _} = jlib:jid_tolower(JID),
|
||||||
|
LUS = {LUser, LServer},
|
||||||
|
case catch mnesia:dirty_select(
|
||||||
|
muc_registered,
|
||||||
|
[{#muc_registered{us_host = '$1',
|
||||||
|
nick = Nick,
|
||||||
|
_ = '_'},
|
||||||
|
[{'==', {element, 2, '$1'}, Host}],
|
||||||
|
['$_']}]) of
|
||||||
|
{'EXIT', _Reason} ->
|
||||||
|
true;
|
||||||
|
[] ->
|
||||||
|
true;
|
||||||
|
[#muc_registered{us_host = {U, _Host}}] ->
|
||||||
|
U == LUS
|
||||||
|
end.
|
||||||
|
|
||||||
|
%%====================================================================
|
||||||
|
%% gen_server callbacks
|
||||||
|
%%====================================================================
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Function: init(Args) -> {ok, State} |
|
||||||
|
%% {ok, State, Timeout} |
|
||||||
|
%% ignore |
|
||||||
|
%% {stop, Reason}
|
||||||
|
%% Description: Initiates the server
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
init([Host, Opts]) ->
|
||||||
mnesia:create_table(muc_room,
|
mnesia:create_table(muc_room,
|
||||||
[{disc_copies, [node()]},
|
[{disc_copies, [node()]},
|
||||||
{attributes, record_info(fields, muc_room)}]),
|
{attributes, record_info(fields, muc_room)}]),
|
||||||
@ -45,40 +148,96 @@ start(Host, Opts) ->
|
|||||||
Access = gen_mod:get_opt(access, Opts, all),
|
Access = gen_mod:get_opt(access, Opts, all),
|
||||||
AccessCreate = gen_mod:get_opt(access_create, Opts, all),
|
AccessCreate = gen_mod:get_opt(access_create, Opts, all),
|
||||||
AccessAdmin = gen_mod:get_opt(access_admin, Opts, none),
|
AccessAdmin = gen_mod:get_opt(access_admin, Opts, none),
|
||||||
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
|
||||||
spawn(?MODULE, init,
|
|
||||||
[MyHost, Host, {Access, AccessCreate, AccessAdmin}])).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
init(Host, ServerHost, Access) ->
|
|
||||||
catch ets:new(muc_online_room, [named_table,
|
catch ets:new(muc_online_room, [named_table,
|
||||||
public,
|
public,
|
||||||
{keypos, #muc_online_room.name_host}]),
|
{keypos, #muc_online_room.name_host}]),
|
||||||
ejabberd_router:register_route(Host),
|
ejabberd_router:register_route(MyHost),
|
||||||
load_permanent_rooms(Host, ServerHost, Access),
|
load_permanent_rooms(MyHost, Host, {Access, AccessCreate, AccessAdmin}),
|
||||||
loop(Host, ServerHost, Access).
|
{ok, #state{host = MyHost,
|
||||||
|
server_host = Host,
|
||||||
|
access = {Access, AccessCreate, AccessAdmin}}}.
|
||||||
|
|
||||||
loop(Host, ServerHost, Access) ->
|
%%--------------------------------------------------------------------
|
||||||
receive
|
%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
|
||||||
{route, From, To, Packet} ->
|
%% {reply, Reply, State, Timeout} |
|
||||||
case catch do_route(Host, ServerHost, Access, From, To, Packet) of
|
%% {noreply, State} |
|
||||||
{'EXIT', Reason} ->
|
%% {noreply, State, Timeout} |
|
||||||
?ERROR_MSG("~p", [Reason]);
|
%% {stop, Reason, Reply, State} |
|
||||||
_ ->
|
%% {stop, Reason, State}
|
||||||
ok
|
%% Description: Handling call messages
|
||||||
end,
|
%%--------------------------------------------------------------------
|
||||||
loop(Host, ServerHost, Access);
|
handle_call(stop, _From, State) ->
|
||||||
{room_destroyed, RoomHost} ->
|
{stop, normal, ok, State}.
|
||||||
ets:delete(muc_online_room, RoomHost),
|
|
||||||
loop(Host, ServerHost, Access);
|
%%--------------------------------------------------------------------
|
||||||
stop ->
|
%% Function: handle_cast(Msg, State) -> {noreply, State} |
|
||||||
ejabberd_router:unregister_route(Host),
|
%% {noreply, State, Timeout} |
|
||||||
ok;
|
%% {stop, Reason, State}
|
||||||
|
%% Description: Handling cast messages
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
handle_cast(_Msg, State) ->
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Function: handle_info(Info, State) -> {noreply, State} |
|
||||||
|
%% {noreply, State, Timeout} |
|
||||||
|
%% {stop, Reason, State}
|
||||||
|
%% Description: Handling all non call/cast messages
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
handle_info({route, From, To, Packet},
|
||||||
|
#state{host = Host,
|
||||||
|
server_host = ServerHost,
|
||||||
|
access = Access} = State) ->
|
||||||
|
case catch do_route(Host, ServerHost, Access, From, To, Packet) of
|
||||||
|
{'EXIT', Reason} ->
|
||||||
|
?ERROR_MSG("~p", [Reason]);
|
||||||
_ ->
|
_ ->
|
||||||
loop(Host, ServerHost, Access)
|
ok
|
||||||
end.
|
end,
|
||||||
|
{noreply, State};
|
||||||
|
handle_info({room_destroyed, RoomHost}, State) ->
|
||||||
|
ets:delete(muc_online_room, RoomHost),
|
||||||
|
{noreply, State};
|
||||||
|
handle_info(_Info, State) ->
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Function: terminate(Reason, State) -> void()
|
||||||
|
%% Description: This function is called by a gen_server when it is about to
|
||||||
|
%% terminate. It should be the opposite of Module:init/1 and do any necessary
|
||||||
|
%% cleaning up. When it returns, the gen_server terminates with Reason.
|
||||||
|
%% The return value is ignored.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
terminate(_Reason, State) ->
|
||||||
|
ejabberd_router:unregister_route(State#state.host),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
|
||||||
|
%% Description: Convert process state when code is changed
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
code_change(_OldVsn, State, _Extra) ->
|
||||||
|
{ok, State}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%%% Internal functions
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
start_supervisor(Host) ->
|
||||||
|
Proc = gen_mod:get_module_proc(Host, ejabberd_mod_muc_sup),
|
||||||
|
ChildSpec =
|
||||||
|
{Proc,
|
||||||
|
{ejabberd_tmp_sup, start_link,
|
||||||
|
[Proc, mod_muc_room]},
|
||||||
|
permanent,
|
||||||
|
infinity,
|
||||||
|
supervisor,
|
||||||
|
[ejabberd_tmp_sup]},
|
||||||
|
supervisor:start_child(ejabberd_sup, ChildSpec).
|
||||||
|
|
||||||
|
stop_supervisor(Host) ->
|
||||||
|
Proc = gen_mod:get_module_proc(Host, ejabberd_mod_muc_sup),
|
||||||
|
supervisor:terminate_child(ejabberd_sup, Proc),
|
||||||
|
supervisor:delete_child(ejabberd_sup, Proc).
|
||||||
|
|
||||||
do_route(Host, ServerHost, Access, From, To, Packet) ->
|
do_route(Host, ServerHost, Access, From, To, Packet) ->
|
||||||
{AccessRoute, _AccessCreate, _AccessAdmin} = Access,
|
{AccessRoute, _AccessCreate, _AccessAdmin} = Access,
|
||||||
@ -252,40 +411,6 @@ do_route1(Host, ServerHost, Access, From, To, Packet) ->
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
room_destroyed(Host, Room, ServerHost) ->
|
|
||||||
gen_mod:get_module_proc(ServerHost, ?PROCNAME) !
|
|
||||||
{room_destroyed, {Room, Host}},
|
|
||||||
ok.
|
|
||||||
|
|
||||||
stop(Host) ->
|
|
||||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
|
||||||
Proc ! stop,
|
|
||||||
{wait, Proc}.
|
|
||||||
|
|
||||||
|
|
||||||
store_room(Host, Name, Opts) ->
|
|
||||||
F = fun() ->
|
|
||||||
mnesia:write(#muc_room{name_host = {Name, Host},
|
|
||||||
opts = Opts})
|
|
||||||
end,
|
|
||||||
mnesia:transaction(F).
|
|
||||||
|
|
||||||
restore_room(Host, Name) ->
|
|
||||||
case catch mnesia:dirty_read(muc_room, {Name, Host}) of
|
|
||||||
[#muc_room{opts = Opts}] ->
|
|
||||||
Opts;
|
|
||||||
_ ->
|
|
||||||
error
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
forget_room(Host, Name) ->
|
|
||||||
F = fun() ->
|
|
||||||
mnesia:delete({muc_room, {Name, Host}})
|
|
||||||
end,
|
|
||||||
mnesia:transaction(F).
|
|
||||||
|
|
||||||
|
|
||||||
load_permanent_rooms(Host, ServerHost, Access) ->
|
load_permanent_rooms(Host, ServerHost, Access) ->
|
||||||
case catch mnesia:dirty_select(
|
case catch mnesia:dirty_select(
|
||||||
muc_room, [{#muc_room{name_host = {'_', Host}, _ = '_'},
|
muc_room, [{#muc_room{name_host = {'_', Host}, _ = '_'},
|
||||||
@ -321,15 +446,6 @@ iq_disco_info() ->
|
|||||||
{xmlelement, "feature", [{"var", ?NS_VCARD}], []}].
|
{xmlelement, "feature", [{"var", ?NS_VCARD}], []}].
|
||||||
|
|
||||||
|
|
||||||
process_iq_disco_items(Host, From, To, #iq{lang = Lang} = IQ) ->
|
|
||||||
Res = IQ#iq{type = result,
|
|
||||||
sub_el = [{xmlelement, "query",
|
|
||||||
[{"xmlns", ?NS_DISCO_ITEMS}],
|
|
||||||
iq_disco_items(Host, From, Lang)}]},
|
|
||||||
ejabberd_router:route(To,
|
|
||||||
From,
|
|
||||||
jlib:iq_to_xml(Res)).
|
|
||||||
|
|
||||||
iq_disco_items(Host, From, Lang) ->
|
iq_disco_items(Host, From, Lang) ->
|
||||||
lists:zf(fun(#muc_online_room{name_host = {Name, _Host}, pid = Pid}) ->
|
lists:zf(fun(#muc_online_room{name_host = {Name, _Host}, pid = Pid}) ->
|
||||||
case catch gen_fsm:sync_send_all_state_event(
|
case catch gen_fsm:sync_send_all_state_event(
|
||||||
@ -482,26 +598,6 @@ get_vh_rooms(Host) ->
|
|||||||
['$_']}]).
|
['$_']}]).
|
||||||
|
|
||||||
|
|
||||||
can_use_nick(_Host, _JID, "") ->
|
|
||||||
false;
|
|
||||||
can_use_nick(Host, JID, Nick) ->
|
|
||||||
{LUser, LServer, _} = jlib:jid_tolower(JID),
|
|
||||||
LUS = {LUser, LServer},
|
|
||||||
case catch mnesia:dirty_select(
|
|
||||||
muc_registered,
|
|
||||||
[{#muc_registered{us_host = '$1',
|
|
||||||
nick = Nick,
|
|
||||||
_ = '_'},
|
|
||||||
[{'==', {element, 2, '$1'}, Host}],
|
|
||||||
['$_']}]) of
|
|
||||||
{'EXIT', _Reason} ->
|
|
||||||
true;
|
|
||||||
[] ->
|
|
||||||
true;
|
|
||||||
[#muc_registered{us_host = {U, _Host}}] ->
|
|
||||||
U == LUS
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
update_tables(Host) ->
|
update_tables(Host) ->
|
||||||
update_muc_room_table(Host),
|
update_muc_room_table(Host),
|
||||||
|
@ -14,7 +14,9 @@
|
|||||||
|
|
||||||
|
|
||||||
%% External exports
|
%% External exports
|
||||||
-export([start/6,
|
-export([start_link/6,
|
||||||
|
start_link/5,
|
||||||
|
start/6,
|
||||||
start/5,
|
start/5,
|
||||||
route/4]).
|
route/4]).
|
||||||
|
|
||||||
@ -84,11 +86,21 @@
|
|||||||
%%% API
|
%%% API
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
start(Host, ServerHost, Access, Room, Creator, Nick) ->
|
start(Host, ServerHost, Access, Room, Creator, Nick) ->
|
||||||
gen_fsm:start(?MODULE, [Host, ServerHost, Access, Room, Creator, Nick],
|
Supervisor = gen_mod:get_module_proc(ServerHost, ejabberd_mod_muc_sup),
|
||||||
?FSMOPTS).
|
supervisor:start_child(
|
||||||
|
Supervisor, [Host, ServerHost, Access, Room, Creator, Nick]).
|
||||||
|
|
||||||
start(Host, ServerHost, Access, Room, Opts) ->
|
start(Host, ServerHost, Access, Room, Opts) ->
|
||||||
gen_fsm:start(?MODULE, [Host, ServerHost, Access, Room, Opts], ?FSMOPTS).
|
Supervisor = gen_mod:get_module_proc(ServerHost, ejabberd_mod_muc_sup),
|
||||||
|
supervisor:start_child(
|
||||||
|
Supervisor, [Host, ServerHost, Access, Room, Opts]).
|
||||||
|
|
||||||
|
start_link(Host, ServerHost, Access, Room, Creator, Nick) ->
|
||||||
|
gen_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, Creator, Nick],
|
||||||
|
?FSMOPTS).
|
||||||
|
|
||||||
|
start_link(Host, ServerHost, Access, Room, Opts) ->
|
||||||
|
gen_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, Opts], ?FSMOPTS).
|
||||||
|
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% Callback functions from gen_fsm
|
%%% Callback functions from gen_fsm
|
||||||
|
@ -10,15 +10,13 @@
|
|||||||
-author('alexey@sevcom.net').
|
-author('alexey@sevcom.net').
|
||||||
-vsn('$Revision$ ').
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
|
-behaviour(gen_server).
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2,
|
%% API
|
||||||
init/4,
|
-export([start_link/2,
|
||||||
loop/2,
|
start/2,
|
||||||
stop/1,
|
stop/1]).
|
||||||
system_continue/3,
|
|
||||||
system_terminate/4,
|
|
||||||
system_code_change/4]).
|
|
||||||
|
|
||||||
-export([delete_item/3,
|
-export([delete_item/3,
|
||||||
set_entities/4,
|
set_entities/4,
|
||||||
@ -28,9 +26,15 @@
|
|||||||
get_node_config/4,
|
get_node_config/4,
|
||||||
set_node_config/4]).
|
set_node_config/4]).
|
||||||
|
|
||||||
|
%% gen_server callbacks
|
||||||
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||||
|
terminate/2, code_change/3]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
|
|
||||||
|
-record(state, {host}).
|
||||||
|
|
||||||
-define(DICT, dict).
|
-define(DICT, dict).
|
||||||
-define(MAXITEMS, 20).
|
-define(MAXITEMS, 20).
|
||||||
-define(MAX_PAYLOAD_SIZE, 100000).
|
-define(MAX_PAYLOAD_SIZE, 100000).
|
||||||
@ -45,60 +49,35 @@
|
|||||||
-record(item, {id, publisher, payload}).
|
-record(item, {id, publisher, payload}).
|
||||||
|
|
||||||
-define(PROCNAME, ejabberd_mod_pubsub).
|
-define(PROCNAME, ejabberd_mod_pubsub).
|
||||||
|
|
||||||
start(Host, Opts) ->
|
|
||||||
mnesia:create_table(pubsub_node,
|
|
||||||
[{disc_only_copies, [node()]},
|
|
||||||
{attributes, record_info(fields, pubsub_node)}]),
|
|
||||||
MyHost = gen_mod:get_opt(host, Opts, "pubsub." ++ Host),
|
|
||||||
update_table(MyHost),
|
|
||||||
mnesia:add_table_index(pubsub_node, host_parent),
|
|
||||||
ServedHosts = gen_mod:get_opt(served_hosts, Opts, []),
|
|
||||||
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
|
||||||
proc_lib:spawn_link(?MODULE, init,
|
|
||||||
[MyHost, Host, ServedHosts, self()])).
|
|
||||||
|
|
||||||
|
|
||||||
-define(MYJID, #jid{user = "", server = Host, resource = "",
|
-define(MYJID, #jid{user = "", server = Host, resource = "",
|
||||||
luser = "", lserver = Host, lresource = ""}).
|
luser = "", lserver = Host, lresource = ""}).
|
||||||
|
|
||||||
init(Host, ServerHost, ServedHosts, Parent) ->
|
%%====================================================================
|
||||||
ejabberd_router:register_route(Host),
|
%% API
|
||||||
create_new_node(Host, ["pubsub"], ?MYJID),
|
%%====================================================================
|
||||||
create_new_node(Host, ["pubsub", "nodes"], ?MYJID),
|
%%--------------------------------------------------------------------
|
||||||
create_new_node(Host, ["home"], ?MYJID),
|
%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
|
||||||
create_new_node(Host, ["home", ServerHost], ?MYJID),
|
%% Description: Starts the server
|
||||||
lists:foreach(fun(H) ->
|
%%--------------------------------------------------------------------
|
||||||
create_new_node(Host, ["home", H], ?MYJID)
|
start_link(Host, Opts) ->
|
||||||
end, ServedHosts),
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
ets:new(gen_mod:get_module_proc(Host, pubsub_presence), [set, named_table]),
|
gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []).
|
||||||
loop(Host, Parent).
|
|
||||||
|
|
||||||
loop(Host, Parent) ->
|
start(Host, Opts) ->
|
||||||
receive
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
{route, From, To, Packet} ->
|
ChildSpec =
|
||||||
case catch do_route(To#jid.lserver, From, To, Packet) of
|
{Proc,
|
||||||
{'EXIT', Reason} ->
|
{?MODULE, start_link, [Host, Opts]},
|
||||||
?ERROR_MSG("~p", [Reason]);
|
temporary,
|
||||||
_ ->
|
1000,
|
||||||
ok
|
worker,
|
||||||
end,
|
[?MODULE]},
|
||||||
loop(Host, Parent);
|
supervisor:start_child(ejabberd_sup, ChildSpec).
|
||||||
{room_destroyed, Room} ->
|
|
||||||
ets:delete(muc_online_room, Room),
|
|
||||||
loop(Host, Parent);
|
|
||||||
stop ->
|
|
||||||
ejabberd_router:unregister_route(Host),
|
|
||||||
ok;
|
|
||||||
reload ->
|
|
||||||
?MODULE:loop(Host, Parent);
|
|
||||||
{system, From, Request} ->
|
|
||||||
sys:handle_system_msg(Request, From, Parent, ?MODULE, [], Host);
|
|
||||||
_ ->
|
|
||||||
loop(Host, Parent)
|
|
||||||
end.
|
|
||||||
|
|
||||||
%%% API functions
|
stop(Host) ->
|
||||||
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
|
gen_server:call(Proc, stop),
|
||||||
|
supervisor:stop_child(ejabberd_sup, Proc).
|
||||||
|
|
||||||
delete_item(From, Node, ItemID) ->
|
delete_item(From, Node, ItemID) ->
|
||||||
delete_item(get_host(), From, Node, ItemID).
|
delete_item(get_host(), From, Node, ItemID).
|
||||||
@ -124,8 +103,98 @@ get_host() ->
|
|||||||
timeout
|
timeout
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%%% Internal functions
|
%%====================================================================
|
||||||
|
%% gen_server callbacks
|
||||||
|
%%====================================================================
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Function: init(Args) -> {ok, State} |
|
||||||
|
%% {ok, State, Timeout} |
|
||||||
|
%% ignore |
|
||||||
|
%% {stop, Reason}
|
||||||
|
%% Description: Initiates the server
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
init([Host, Opts]) ->
|
||||||
|
mnesia:create_table(pubsub_node,
|
||||||
|
[{disc_only_copies, [node()]},
|
||||||
|
{attributes, record_info(fields, pubsub_node)}]),
|
||||||
|
MyHost = gen_mod:get_opt(host, Opts, "pubsub." ++ Host),
|
||||||
|
update_table(MyHost),
|
||||||
|
mnesia:add_table_index(pubsub_node, host_parent),
|
||||||
|
ServedHosts = gen_mod:get_opt(served_hosts, Opts, []),
|
||||||
|
|
||||||
|
|
||||||
|
ejabberd_router:register_route(MyHost),
|
||||||
|
create_new_node(MyHost, ["pubsub"], ?MYJID),
|
||||||
|
create_new_node(MyHost, ["pubsub", "nodes"], ?MYJID),
|
||||||
|
create_new_node(MyHost, ["home"], ?MYJID),
|
||||||
|
create_new_node(MyHost, ["home", Host], ?MYJID),
|
||||||
|
lists:foreach(fun(H) ->
|
||||||
|
create_new_node(MyHost, ["home", H], ?MYJID)
|
||||||
|
end, ServedHosts),
|
||||||
|
ets:new(gen_mod:get_module_proc(MyHost, pubsub_presence),
|
||||||
|
[set, named_table]),
|
||||||
|
{ok, #state{host = MyHost}}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
|
||||||
|
%% {reply, Reply, State, Timeout} |
|
||||||
|
%% {noreply, State} |
|
||||||
|
%% {noreply, State, Timeout} |
|
||||||
|
%% {stop, Reason, Reply, State} |
|
||||||
|
%% {stop, Reason, State}
|
||||||
|
%% Description: Handling call messages
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
handle_call(stop, _From, State) ->
|
||||||
|
{stop, normal, ok, State}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Function: handle_cast(Msg, State) -> {noreply, State} |
|
||||||
|
%% {noreply, State, Timeout} |
|
||||||
|
%% {stop, Reason, State}
|
||||||
|
%% Description: Handling cast messages
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
handle_cast(_Msg, State) ->
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Function: handle_info(Info, State) -> {noreply, State} |
|
||||||
|
%% {noreply, State, Timeout} |
|
||||||
|
%% {stop, Reason, State}
|
||||||
|
%% Description: Handling all non call/cast messages
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
handle_info({route, From, To, Packet}, State) ->
|
||||||
|
case catch do_route(To#jid.lserver, From, To, Packet) of
|
||||||
|
{'EXIT', Reason} ->
|
||||||
|
?ERROR_MSG("~p", [Reason]);
|
||||||
|
_ ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
{noreply, State};
|
||||||
|
handle_info(_Info, State) ->
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Function: terminate(Reason, State) -> void()
|
||||||
|
%% Description: This function is called by a gen_server when it is about to
|
||||||
|
%% terminate. It should be the opposite of Module:init/1 and do any necessary
|
||||||
|
%% cleaning up. When it returns, the gen_server terminates with Reason.
|
||||||
|
%% The return value is ignored.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
terminate(_Reason, State) ->
|
||||||
|
ejabberd_router:unregister_route(State#state.host),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
|
||||||
|
%% Description: Convert process state when code is changed
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
code_change(_OldVsn, State, _Extra) ->
|
||||||
|
{ok, State}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%%% Internal functions
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
do_route(Host, From, To, Packet) ->
|
do_route(Host, From, To, Packet) ->
|
||||||
{xmlelement, Name, Attrs, Els} = Packet,
|
{xmlelement, Name, Attrs, Els} = Packet,
|
||||||
case To of
|
case To of
|
||||||
@ -236,14 +305,6 @@ do_route(Host, From, To, Packet) ->
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
stop(Host) ->
|
|
||||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
|
||||||
Proc ! stop,
|
|
||||||
{wait, Proc}.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
node_to_string(Node) ->
|
node_to_string(Node) ->
|
||||||
string:strip(lists:flatten(lists:map(fun(S) -> [S, "/"] end, Node)),
|
string:strip(lists:flatten(lists:map(fun(S) -> [S, "/"] end, Node)),
|
||||||
right, $/).
|
right, $/).
|
||||||
@ -1261,18 +1322,6 @@ broadcast_config_notification(Host, Node, Lang) ->
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
system_continue(Parent, _, State) ->
|
|
||||||
loop(State, Parent).
|
|
||||||
|
|
||||||
system_terminate(Reason, Parent, _, State) ->
|
|
||||||
exit(Reason).
|
|
||||||
|
|
||||||
system_code_change(State, _Mod, Ver, _Extra) ->
|
|
||||||
{ok, State}.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
iq_pubsub_owner(Host, From, Type, Lang, SubEl) ->
|
iq_pubsub_owner(Host, From, Type, Lang, SubEl) ->
|
||||||
{xmlelement, _, _, SubEls} = SubEl,
|
{xmlelement, _, _, SubEls} = SubEl,
|
||||||
case xml:remove_cdata(SubEls) of
|
case xml:remove_cdata(SubEls) of
|
||||||
|
Loading…
Reference in New Issue
Block a user