* 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:
Alexey Shchepin 2006-02-02 05:00:27 +00:00
parent 50f44530d2
commit 971001e7aa
5 changed files with 444 additions and 197 deletions

View File

@ -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>

View File

@ -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
%%--------------------------------------------------------------------

View File

@ -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),

View File

@ -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

View File

@ -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