Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/processone/ejabberd.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexey Shchepin <alexey@process-one.net>2006-01-29 07:38:31 +0300
committerAlexey Shchepin <alexey@process-one.net>2006-01-29 07:38:31 +0300
commit50f44530d2943e91ab2d4e3d08ced8f8c2689dab (patch)
treedfca1c0ee75f69095a117ec17d759b950fbd4258 /src
parentef456ab64591d20c8704f2c674415cc93d87f09c (diff)
* src/odbc/pg.sql: Fixed syntax error
* src/ejabberd_router.erl: Updated to use gen_server behaviour * src/ejabberd_sm.erl: Likewise * src/ejabberd_s2s.erl: Likewise * src/gen_iq_handler.erl: Likewise * src/ejabberd_sup.erl: Added supervisor for ejabberd_receiver * src/ejabberd_receiver.erl: Updated SVN Revision: 495
Diffstat (limited to 'src')
-rw-r--r--src/ejabberd_local.erl252
-rw-r--r--src/ejabberd_receiver.erl14
-rw-r--r--src/ejabberd_router.erl268
-rw-r--r--src/ejabberd_s2s.erl167
-rw-r--r--src/ejabberd_sm.erl309
-rw-r--r--src/ejabberd_sup.erl9
-rw-r--r--src/ejabberd_update.erl14
-rw-r--r--src/gen_iq_handler.erl118
-rw-r--r--src/odbc/pg.sql12
9 files changed, 763 insertions, 400 deletions
diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl
index a9fa5ee2e..afb5332a7 100644
--- a/src/ejabberd_local.erl
+++ b/src/ejabberd_local.erl
@@ -10,7 +10,10 @@
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
--export([start_link/0, init/0]).
+-behaviour(gen_server).
+
+%% API
+-export([start_link/0]).
-export([route/3,
register_iq_handler/4,
@@ -20,102 +23,26 @@
bounce_resource_packet/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("jlib.hrl").
+-record(state, {}).
+
-define(IQTABLE, local_iqtable).
+%%====================================================================
+%% API
+%%====================================================================
+%%--------------------------------------------------------------------
+%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
+%% Description: Starts the server
+%%--------------------------------------------------------------------
start_link() ->
- register(ejabberd_local,
- Pid = proc_lib:spawn_link(ejabberd_local, init, [])),
- {ok, Pid}.
-
-init() ->
- lists:foreach(
- fun(Host) ->
- ejabberd_router:register_route(Host, {apply, ?MODULE, route}),
- ejabberd_hooks:add(local_send_to_resource_hook, Host,
- ?MODULE, bounce_resource_packet, 100)
- end, ?MYHOSTS),
- catch ets:new(?IQTABLE, [named_table, public]),
- loop().
-
-loop() ->
- receive
- {route, From, To, Packet} ->
- case catch do_route(From, To, Packet) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p~nwhen processing: ~p",
- [Reason, {From, To, Packet}]);
- _ ->
- ok
- end,
- loop();
- {register_iq_handler, Host, XMLNS, Module, Function} ->
- ets:insert(?IQTABLE, {{XMLNS, Host}, Module, Function}),
- catch mod_disco:register_feature(Host, XMLNS),
- loop();
- {register_iq_handler, Host, XMLNS, Module, Function, Opts} ->
- ets:insert(?IQTABLE, {{XMLNS, Host}, Module, Function, Opts}),
- catch mod_disco:register_feature(Host, XMLNS),
- loop();
- {unregister_iq_handler, Host, XMLNS} ->
- case ets:lookup(?IQTABLE, {XMLNS, Host}) of
- [{_, Module, Function, Opts}] ->
- gen_iq_handler:stop_iq_handler(Module, Function, Opts);
- _ ->
- ok
- end,
- ets:delete(?IQTABLE, {XMLNS, Host}),
- catch mod_disco:unregister_feature(Host, XMLNS),
- loop();
- refresh_iq_handlers ->
- lists:foreach(
- fun(T) ->
- case T of
- {{XMLNS, Host}, _Module, _Function, _Opts} ->
- catch mod_disco:register_feature(Host, XMLNS);
- {{XMLNS, Host}, _Module, _Function} ->
- catch mod_disco:register_feature(Host, XMLNS);
- _ ->
- ok
- end
- end, ets:tab2list(?IQTABLE)),
- loop();
- _ ->
- loop()
- end.
-
-
-do_route(From, To, Packet) ->
- ?DEBUG("local route~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
- [From, To, Packet, 8]),
- if
- To#jid.luser /= "" ->
- ejabberd_sm:route(From, To, Packet);
- To#jid.lresource == "" ->
- {xmlelement, Name, Attrs, _Els} = Packet,
- case Name of
- "iq" ->
- process_iq(From, To, Packet);
- "message" ->
- ok;
- "presence" ->
- ok;
- _ ->
- ok
- end;
- true ->
- {xmlelement, Name, Attrs, _Els} = Packet,
- case xml:get_attr_s("type", Attrs) of
- "error" -> ok;
- "result" -> ok;
- _ ->
- ejabberd_hooks:run(local_send_to_resource_hook,
- To#jid.lserver,
- [From, To, Packet])
- end
- end.
+ gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
process_iq(From, To, Packet) ->
IQ = jlib:iq_query_info(Packet),
@@ -173,3 +100,146 @@ bounce_resource_packet(From, To, Packet) ->
Err = jlib:make_error_reply(Packet, ?ERR_ITEM_NOT_FOUND),
ejabberd_router:route(To, From, Err),
stop.
+
+%%====================================================================
+%% gen_server callbacks
+%%====================================================================
+
+%%--------------------------------------------------------------------
+%% Function: init(Args) -> {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%% Description: Initiates the server
+%%--------------------------------------------------------------------
+init([]) ->
+ lists:foreach(
+ fun(Host) ->
+ ejabberd_router:register_route(Host, {apply, ?MODULE, route}),
+ ejabberd_hooks:add(local_send_to_resource_hook, Host,
+ ?MODULE, bounce_resource_packet, 100)
+ end, ?MYHOSTS),
+ catch ets:new(?IQTABLE, [named_table, public]),
+ {ok, #state{}}.
+
+%%--------------------------------------------------------------------
+%% 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(_Request, _From, State) ->
+ Reply = ok,
+ {reply, Reply, 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(From, To, Packet) of
+ {'EXIT', Reason} ->
+ ?ERROR_MSG("~p~nwhen processing: ~p",
+ [Reason, {From, To, Packet}]);
+ _ ->
+ ok
+ end,
+ {noreply, State};
+handle_info({register_iq_handler, Host, XMLNS, Module, Function}, State) ->
+ ets:insert(?IQTABLE, {{XMLNS, Host}, Module, Function}),
+ catch mod_disco:register_feature(Host, XMLNS),
+ {noreply, State};
+handle_info({register_iq_handler, Host, XMLNS, Module, Function, Opts}, State) ->
+ ets:insert(?IQTABLE, {{XMLNS, Host}, Module, Function, Opts}),
+ catch mod_disco:register_feature(Host, XMLNS),
+ {noreply, State};
+handle_info({unregister_iq_handler, Host, XMLNS}, State) ->
+ case ets:lookup(?IQTABLE, {XMLNS, Host}) of
+ [{_, Module, Function, Opts}] ->
+ gen_iq_handler:stop_iq_handler(Module, Function, Opts);
+ _ ->
+ ok
+ end,
+ ets:delete(?IQTABLE, {XMLNS, Host}),
+ catch mod_disco:unregister_feature(Host, XMLNS),
+ {noreply, State};
+handle_info(refresh_iq_handlers, State) ->
+ lists:foreach(
+ fun(T) ->
+ case T of
+ {{XMLNS, Host}, _Module, _Function, _Opts} ->
+ catch mod_disco:register_feature(Host, XMLNS);
+ {{XMLNS, Host}, _Module, _Function} ->
+ catch mod_disco:register_feature(Host, XMLNS);
+ _ ->
+ ok
+ end
+ end, ets:tab2list(?IQTABLE)),
+ {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) ->
+ 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(From, To, Packet) ->
+ ?DEBUG("local route~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
+ [From, To, Packet, 8]),
+ if
+ To#jid.luser /= "" ->
+ ejabberd_sm:route(From, To, Packet);
+ To#jid.lresource == "" ->
+ {xmlelement, Name, _Attrs, _Els} = Packet,
+ case Name of
+ "iq" ->
+ process_iq(From, To, Packet);
+ "message" ->
+ ok;
+ "presence" ->
+ ok;
+ _ ->
+ ok
+ end;
+ true ->
+ {xmlelement, _Name, Attrs, _Els} = Packet,
+ case xml:get_attr_s("type", Attrs) of
+ "error" -> ok;
+ "result" -> ok;
+ _ ->
+ ejabberd_hooks:run(local_send_to_resource_hook,
+ To#jid.lserver,
+ [From, To, Packet])
+ end
+ end.
+
diff --git a/src/ejabberd_receiver.erl b/src/ejabberd_receiver.erl
index 6977c8931..03618b520 100644
--- a/src/ejabberd_receiver.erl
+++ b/src/ejabberd_receiver.erl
@@ -13,7 +13,8 @@
-behaviour(gen_server).
%% API
--export([start/3,
+-export([start_link/4,
+ start/3,
change_shaper/2,
reset_stream/1,
starttls/2,
@@ -38,12 +39,19 @@
%% API
%%====================================================================
%%--------------------------------------------------------------------
+%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
+%% Description: Starts the server
+%%--------------------------------------------------------------------
+start_link(Socket, SockMod, Shaper, C2SPid) ->
+ gen_server:start_link(?MODULE, [Socket, SockMod, Shaper, C2SPid], []).
+
+%%--------------------------------------------------------------------
%% Function: start() -> {ok,Pid} | ignore | {error,Error}
%% Description: Starts the server
%%--------------------------------------------------------------------
start(Socket, SockMod, Shaper) ->
- {ok, Pid} = gen_server:start(
- ?MODULE, [Socket, SockMod, Shaper, self()], []),
+ {ok, Pid} = supervisor:start_child(ejabberd_receiver_sup,
+ [Socket, SockMod, Shaper, self()]),
Pid.
change_shaper(Pid, Shaper) ->
diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl
index 4fd85f2c9..20f0c998c 100644
--- a/src/ejabberd_router.erl
+++ b/src/ejabberd_router.erl
@@ -10,6 +10,9 @@
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
+-behaviour(gen_server).
+
+%% API
-export([route/3,
register_route/1,
register_route/2,
@@ -20,114 +23,28 @@
dirty_get_all_domains/0
]).
--export([start_link/0, init/0]).
+-export([start_link/0]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2, code_change/3]).
-include("ejabberd.hrl").
-include("jlib.hrl").
-record(route, {domain, pid, local_hint}).
+-record(state, {}).
-
+%%====================================================================
+%% API
+%%====================================================================
+%%--------------------------------------------------------------------
+%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
+%% Description: Starts the server
+%%--------------------------------------------------------------------
start_link() ->
- update_tables(),
- mnesia:create_table(route,
- [{ram_copies, [node()]},
- {type, bag},
- {attributes,
- record_info(fields, route)}]),
- mnesia:add_table_copy(route, node(), ram_copies),
- Pid = proc_lib:spawn_link(ejabberd_router, init, []),
- register(ejabberd_router, Pid),
- {ok, Pid}.
+ gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-init() ->
- mnesia:subscribe({table, route, simple}),
- lists:foreach(
- fun(Pid) ->
- erlang:monitor(process, Pid)
- end,
- mnesia:dirty_select(route, [{{route, '_', '$1', '_'}, [], ['$1']}])),
- loop().
-
-loop() ->
- receive
- {route, From, To, Packet} ->
- case catch do_route(From, To, Packet) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p~nwhen processing: ~p",
- [Reason, {From, To, Packet}]);
- _ ->
- ok
- end,
- loop();
- {mnesia_table_event, {write, #route{pid = Pid}, _ActivityId}} ->
- erlang:monitor(process, Pid),
- loop();
- {'DOWN', _Ref, _Type, Pid, _Info} ->
- F = fun() ->
- Es = mnesia:select(
- route,
- [{#route{pid = Pid, _ = '_'},
- [],
- ['$_']}]),
- lists:foreach(fun(E) ->
- mnesia:delete_object(E)
- end, Es)
- end,
- mnesia:transaction(F),
- loop();
- _ ->
- loop()
- end.
-
-do_route(OrigFrom, OrigTo, OrigPacket) ->
- ?DEBUG("route~n\tfrom ~p~n\tto ~p~n\tpacket ~p~n",
- [OrigFrom, OrigTo, OrigPacket]),
- LOrigDstDomain = OrigTo#jid.lserver,
- case ejabberd_hooks:run_fold(filter_packet, LOrigDstDomain,
- {OrigFrom, OrigTo, OrigPacket}, []) of
- {From, To, Packet} ->
- LDstDomain = To#jid.lserver,
- case mnesia:dirty_read(route, LDstDomain) of
- [] ->
- ejabberd_s2s:route(From, To, Packet);
- [R] ->
- Pid = R#route.pid,
- if
- node(Pid) == node() ->
- case R#route.local_hint of
- {apply, Module, Function} ->
- Module:Function(From, To, Packet);
- _ ->
- Pid ! {route, From, To, Packet}
- end;
- true ->
- Pid ! {route, From, To, Packet}
- end;
- Rs ->
- case [R || R <- Rs, node(R#route.pid) == node()] of
- [] ->
- R = lists:nth(erlang:phash(now(), length(Rs)), Rs),
- Pid = R#route.pid,
- Pid ! {route, From, To, Packet};
- LRs ->
- LRs,
- R = lists:nth(erlang:phash(now(), length(LRs)), LRs),
- Pid = R#route.pid,
- case R#route.local_hint of
- {apply, Module, Function} ->
- Module:Function(From, To, Packet);
- _ ->
- Pid ! {route, From, To, Packet}
- end
- end
- end;
- drop ->
- ok
- end.
-
-%route(From, To, Packet) ->
-% ejabberd_router ! {route, From, To, Packet}.
route(From, To, Packet) ->
case catch do_route(From, To, Packet) of
@@ -196,6 +113,157 @@ dirty_get_all_domains() ->
lists:usort(mnesia:dirty_all_keys(route)).
+%%====================================================================
+%% gen_server callbacks
+%%====================================================================
+
+%%--------------------------------------------------------------------
+%% Function: init(Args) -> {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%% Description: Initiates the server
+%%--------------------------------------------------------------------
+init([]) ->
+ update_tables(),
+ mnesia:create_table(route,
+ [{ram_copies, [node()]},
+ {type, bag},
+ {attributes,
+ record_info(fields, route)}]),
+ mnesia:add_table_copy(route, node(), ram_copies),
+ mnesia:subscribe({table, route, simple}),
+ lists:foreach(
+ fun(Pid) ->
+ erlang:monitor(process, Pid)
+ end,
+ mnesia:dirty_select(route, [{{route, '_', '$1', '_'}, [], ['$1']}])),
+ {ok, #state{}}.
+
+%%--------------------------------------------------------------------
+%% 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(_Request, _From, State) ->
+ Reply = ok,
+ {reply, Reply, 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(From, To, Packet) of
+ {'EXIT', Reason} ->
+ ?ERROR_MSG("~p~nwhen processing: ~p",
+ [Reason, {From, To, Packet}]);
+ _ ->
+ ok
+ end,
+ {noreply, State};
+handle_info({mnesia_table_event, {write, #route{pid = Pid}, _ActivityId}},
+ State) ->
+ erlang:monitor(process, Pid),
+ {noreply, State};
+handle_info({'DOWN', _Ref, _Type, Pid, _Info}, State) ->
+ F = fun() ->
+ Es = mnesia:select(
+ route,
+ [{#route{pid = Pid, _ = '_'},
+ [],
+ ['$_']}]),
+ lists:foreach(fun(E) ->
+ mnesia:delete_object(E)
+ end, Es)
+ end,
+ mnesia:transaction(F),
+ {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) ->
+ 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(OrigFrom, OrigTo, OrigPacket) ->
+ ?DEBUG("route~n\tfrom ~p~n\tto ~p~n\tpacket ~p~n",
+ [OrigFrom, OrigTo, OrigPacket]),
+ LOrigDstDomain = OrigTo#jid.lserver,
+ case ejabberd_hooks:run_fold(filter_packet, LOrigDstDomain,
+ {OrigFrom, OrigTo, OrigPacket}, []) of
+ {From, To, Packet} ->
+ LDstDomain = To#jid.lserver,
+ case mnesia:dirty_read(route, LDstDomain) of
+ [] ->
+ ejabberd_s2s:route(From, To, Packet);
+ [R] ->
+ Pid = R#route.pid,
+ if
+ node(Pid) == node() ->
+ case R#route.local_hint of
+ {apply, Module, Function} ->
+ Module:Function(From, To, Packet);
+ _ ->
+ Pid ! {route, From, To, Packet}
+ end;
+ true ->
+ Pid ! {route, From, To, Packet}
+ end;
+ Rs ->
+ case [R || R <- Rs, node(R#route.pid) == node()] of
+ [] ->
+ R = lists:nth(erlang:phash(now(), length(Rs)), Rs),
+ Pid = R#route.pid,
+ Pid ! {route, From, To, Packet};
+ LRs ->
+ LRs,
+ R = lists:nth(erlang:phash(now(), length(LRs)), LRs),
+ Pid = R#route.pid,
+ case R#route.local_hint of
+ {apply, Module, Function} ->
+ Module:Function(From, To, Packet);
+ _ ->
+ Pid ! {route, From, To, Packet}
+ end
+ end
+ end;
+ drop ->
+ ok
+ end.
+
+
update_tables() ->
case catch mnesia:table_info(route, attributes) of
diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl
index 7a07861f0..f5aac6b8a 100644
--- a/src/ejabberd_s2s.erl
+++ b/src/ejabberd_s2s.erl
@@ -10,7 +10,10 @@
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
--export([start_link/0, init/0,
+-behaviour(gen_server).
+
+%% API
+-export([start_link/0,
route/3,
have_connection/1,
get_key/1,
@@ -18,43 +21,25 @@
remove_connection/1,
dirty_get_connections/0]).
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2, code_change/3]).
+
-include("ejabberd.hrl").
-include("jlib.hrl").
-record(s2s, {fromto, pid, key}).
+-record(state, {}).
-
+%%====================================================================
+%% API
+%%====================================================================
+%%--------------------------------------------------------------------
+%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
+%% Description: Starts the server
+%%--------------------------------------------------------------------
start_link() ->
- Pid = proc_lib:spawn_link(ejabberd_s2s, init, []),
- register(ejabberd_s2s, Pid),
- {ok, Pid}.
-
-init() ->
- update_tables(),
- mnesia:create_table(s2s, [{ram_copies, [node()]},
- {attributes, record_info(fields, s2s)}]),
- mnesia:add_table_copy(s2s, node(), ram_copies),
- mnesia:subscribe(system),
- loop().
-
-loop() ->
- receive
- {mnesia_system_event, {mnesia_down, Node}} ->
- clean_table_from_bad_node(Node),
- loop();
- {route, From, To, Packet} ->
- case catch do_route(From, To, Packet) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p~nwhen processing: ~p",
- [Reason, {From, To, Packet}]);
- _ ->
- ok
- end,
- loop();
- _ ->
- loop()
- end.
-
+ gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
route(From, To, Packet) ->
case catch do_route(From, To, Packet) of
@@ -65,28 +50,12 @@ route(From, To, Packet) ->
ok
end.
-
remove_connection(FromTo) ->
F = fun() ->
mnesia:delete({s2s, FromTo})
end,
mnesia:transaction(F).
-
-
-clean_table_from_bad_node(Node) ->
- F = fun() ->
- Es = mnesia:select(
- s2s,
- [{#s2s{pid = '$1', _ = '_'},
- [{'==', {node, '$1'}, Node}],
- ['$_']}]),
- lists:foreach(fun(E) ->
- mnesia:delete_object(E)
- end, Es)
- end,
- mnesia:transaction(F).
-
have_connection(FromTo) ->
case catch mnesia:dirty_read(s2s, FromTo) of
[_] ->
@@ -123,9 +92,103 @@ try_register(FromTo) ->
false
end.
+dirty_get_connections() ->
+ mnesia:dirty_all_keys(s2s).
+
+%%====================================================================
+%% gen_server callbacks
+%%====================================================================
+
+%%--------------------------------------------------------------------
+%% Function: init(Args) -> {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%% Description: Initiates the server
+%%--------------------------------------------------------------------
+init([]) ->
+ update_tables(),
+ mnesia:create_table(s2s, [{ram_copies, [node()]},
+ {attributes, record_info(fields, s2s)}]),
+ mnesia:add_table_copy(s2s, node(), ram_copies),
+ mnesia:subscribe(system),
+ {ok, #state{}}.
+
+%%--------------------------------------------------------------------
+%% 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(_Request, _From, State) ->
+ Reply = ok,
+ {reply, Reply, 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({mnesia_system_event, {mnesia_down, Node}}, State) ->
+ clean_table_from_bad_node(Node),
+ {noreply, State};
+handle_info({route, From, To, Packet}, State) ->
+ case catch do_route(From, To, Packet) of
+ {'EXIT', Reason} ->
+ ?ERROR_MSG("~p~nwhen processing: ~p",
+ [Reason, {From, To, Packet}]);
+ _ ->
+ 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) ->
+ 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
+%%--------------------------------------------------------------------
+clean_table_from_bad_node(Node) ->
+ F = fun() ->
+ Es = mnesia:select(
+ s2s,
+ [{#s2s{pid = '$1', _ = '_'},
+ [{'==', {node, '$1'}, Node}],
+ ['$_']}]),
+ lists:foreach(fun(E) ->
+ mnesia:delete_object(E)
+ end, Es)
+ end,
+ mnesia:transaction(F).
do_route(From, To, Packet) ->
?DEBUG("s2s manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
@@ -174,15 +237,9 @@ find_connection(From, To) ->
{atomic, El#s2s.pid}
end.
-
send_element(Pid, El) ->
Pid ! {send_element, El}.
-
-dirty_get_connections() ->
- mnesia:dirty_all_keys(s2s).
-
-
update_tables() ->
case catch mnesia:table_info(s2s, attributes) of
[fromto, node, key] ->
diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl
index 34d2fec47..dffb3c0da 100644
--- a/src/ejabberd_sm.erl
+++ b/src/ejabberd_sm.erl
@@ -10,7 +10,10 @@
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
--export([start_link/0, init/0,
+-behaviour(gen_server).
+
+%% API
+-export([start_link/0,
route/3,
open_session/4, close_session/1,
bounce_offline_message/3,
@@ -27,17 +30,124 @@
unregister_iq_handler/2
]).
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2, code_change/3]).
+
-include("ejabberd.hrl").
-include("jlib.hrl").
-record(session, {sid, usr, us, priority}).
-
+-record(state, {}).
+
+%%====================================================================
+%% API
+%%====================================================================
+%%--------------------------------------------------------------------
+%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
+%% Description: Starts the server
+%%--------------------------------------------------------------------
start_link() ->
- Pid = proc_lib:spawn_link(ejabberd_sm, init, []),
- register(ejabberd_sm, Pid),
- {ok, Pid}.
+ gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
+
+route(From, To, Packet) ->
+ case catch do_route(From, To, Packet) of
+ {'EXIT', Reason} ->
+ ?ERROR_MSG("~p~nwhen processing: ~p",
+ [Reason, {From, To, Packet}]);
+ _ ->
+ ok
+ end.
+
+open_session(SID, User, Server, Resource) ->
+ set_session(SID, User, Server, Resource, undefined).
+
+close_session(SID) ->
+ F = fun() ->
+ mnesia:delete({session, SID})
+ end,
+ mnesia:sync_dirty(F).
+
+bounce_offline_message(From, To, Packet) ->
+ Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE),
+ ejabberd_router:route(To, From, Err),
+ stop.
+
+disconnect_removed_user(User, Server) ->
+ ejabberd_sm:route(jlib:make_jid("", "", ""),
+ jlib:make_jid(User, Server, ""),
+ {xmlelement, "broadcast", [],
+ [{exit, "User removed"}]}).
+
+get_user_resources(User, Server) ->
+ LUser = jlib:nodeprep(User),
+ LServer = jlib:nameprep(Server),
+ US = {LUser, LServer},
+ case catch mnesia:dirty_index_read(session, US, #session.us) of
+ {'EXIT', _Reason} ->
+ [];
+ Ss ->
+ [element(3, S#session.usr) || S <- clean_session_list(Ss)]
+ end.
+
+set_presence(SID, User, Server, Resource, Priority) ->
+ set_session(SID, User, Server, Resource, Priority).
-init() ->
+unset_presence(SID, User, Server, Resource, Status) ->
+ set_session(SID, User, Server, Resource, undefined),
+ ejabberd_hooks:run(unset_presence_hook, jlib:nameprep(Server),
+ [User, Server, Resource, Status]).
+
+close_session_unset_presence(SID, User, Server, Resource, Status) ->
+ close_session(SID),
+ ejabberd_hooks:run(unset_presence_hook, jlib:nameprep(Server),
+ [User, Server, Resource, Status]).
+
+
+dirty_get_sessions_list() ->
+ mnesia:dirty_select(
+ session,
+ [{#session{usr = '$1', _ = '_'},
+ [],
+ ['$1']}]).
+
+dirty_get_my_sessions_list() ->
+ mnesia:dirty_select(
+ session,
+ [{#session{sid = {'_', '$1'}, _ = '_'},
+ [{'==', {node, '$1'}, node()}],
+ ['$_']}]).
+
+get_vh_session_list(Server) ->
+ LServer = jlib:nameprep(Server),
+ mnesia:dirty_select(
+ session,
+ [{#session{usr = '$1', _ = '_'},
+ [{'==', {element, 2, '$1'}, LServer}],
+ ['$1']}]).
+
+register_iq_handler(Host, XMLNS, Module, Fun) ->
+ ejabberd_sm ! {register_iq_handler, Host, XMLNS, Module, Fun}.
+
+register_iq_handler(Host, XMLNS, Module, Fun, Opts) ->
+ ejabberd_sm ! {register_iq_handler, Host, XMLNS, Module, Fun, Opts}.
+
+unregister_iq_handler(Host, XMLNS) ->
+ ejabberd_sm ! {unregister_iq_handler, Host, XMLNS}.
+
+
+%%====================================================================
+%% gen_server callbacks
+%%====================================================================
+
+%%--------------------------------------------------------------------
+%% Function: init(Args) -> {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%% Description: Initiates the server
+%%--------------------------------------------------------------------
+init([]) ->
update_tables(),
mnesia:create_table(session,
[{ram_copies, [node()]},
@@ -54,53 +164,86 @@ init() ->
ejabberd_hooks:add(remove_user, Host,
ejabberd_sm, disconnect_removed_user, 100)
end, ?MYHOSTS),
- loop().
-
-loop() ->
- receive
- {route, From, To, Packet} ->
- case catch do_route(From, To, Packet) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p~nwhen processing: ~p",
- [Reason, {From, To, Packet}]);
- _ ->
- ok
- end,
- loop();
- {mnesia_system_event, {mnesia_down, Node}} ->
- clean_table_from_bad_node(Node),
- loop();
- {register_iq_handler, Host, XMLNS, Module, Function} ->
- ets:insert(sm_iqtable, {{XMLNS, Host}, Module, Function}),
- loop();
- {register_iq_handler, Host, XMLNS, Module, Function, Opts} ->
- ets:insert(sm_iqtable, {{XMLNS, Host}, Module, Function, Opts}),
- loop();
- {unregister_iq_handler, Host, XMLNS} ->
- case ets:lookup(sm_iqtable, {XMLNS, Host}) of
- [{_, Module, Function, Opts}] ->
- gen_iq_handler:stop_iq_handler(Module, Function, Opts);
- _ ->
- ok
- end,
- ets:delete(sm_iqtable, {XMLNS, Host}),
- loop();
- _ ->
- loop()
- end.
-
-
-route(From, To, Packet) ->
+ {ok, #state{}}.
+
+%%--------------------------------------------------------------------
+%% 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(_Request, _From, State) ->
+ Reply = ok,
+ {reply, Reply, 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(From, To, Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
[Reason, {From, To, Packet}]);
_ ->
ok
- end.
-
-open_session(SID, User, Server, Resource) ->
- set_session(SID, User, Server, Resource, undefined).
+ end,
+ {noreply, State};
+handle_info({mnesia_system_event, {mnesia_down, Node}}, State) ->
+ clean_table_from_bad_node(Node),
+ {noreply, State};
+handle_info({register_iq_handler, Host, XMLNS, Module, Function}, State) ->
+ ets:insert(sm_iqtable, {{XMLNS, Host}, Module, Function}),
+ {noreply, State};
+handle_info({register_iq_handler, Host, XMLNS, Module, Function, Opts}, State) ->
+ ets:insert(sm_iqtable, {{XMLNS, Host}, Module, Function, Opts}),
+ {noreply, State};
+handle_info({unregister_iq_handler, Host, XMLNS}, State) ->
+ case ets:lookup(sm_iqtable, {XMLNS, Host}) of
+ [{_, Module, Function, Opts}] ->
+ gen_iq_handler:stop_iq_handler(Module, Function, Opts);
+ _ ->
+ ok
+ end,
+ ets:delete(sm_iqtable, {XMLNS, Host}),
+ {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) ->
+ 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
+%%--------------------------------------------------------------------
set_session(SID, User, Server, Resource, Priority) ->
LUser = jlib:nodeprep(User),
@@ -131,12 +274,6 @@ set_session(SID, User, Server, Resource, Priority) ->
end, SIDs)
end.
-close_session(SID) ->
- F = fun() ->
- mnesia:delete({session, SID})
- end,
- mnesia:sync_dirty(F).
-
clean_table_from_bad_node(Node) ->
F = fun() ->
@@ -314,31 +451,9 @@ route_message(From, To, Packet) ->
end
end.
-bounce_offline_message(From, To, Packet) ->
- Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE),
- ejabberd_router:route(To, From, Err),
- stop.
-
-disconnect_removed_user(User, Server) ->
- ejabberd_sm:route(jlib:make_jid("", "", ""),
- jlib:make_jid(User, Server, ""),
- {xmlelement, "broadcast", [],
- [{exit, "User removed"}]}).
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-get_user_resources(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- US = {LUser, LServer},
- case catch mnesia:dirty_index_read(session, US, #session.us) of
- {'EXIT', _Reason} ->
- [];
- Ss ->
- [element(3, S#session.usr) || S <- clean_session_list(Ss)]
- end.
-
clean_session_list(Ss) ->
clean_session_list(lists:keysort(#session.usr, Ss), []).
@@ -362,19 +477,6 @@ clean_session_list([S1, S2 | Rest], Res) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-set_presence(SID, User, Server, Resource, Priority) ->
- set_session(SID, User, Server, Resource, Priority).
-
-unset_presence(SID, User, Server, Resource, Status) ->
- set_session(SID, User, Server, Resource, undefined),
- ejabberd_hooks:run(unset_presence_hook, jlib:nameprep(Server),
- [User, Server, Resource, Status]).
-
-close_session_unset_presence(SID, User, Server, Resource, Status) ->
- close_session(SID),
- ejabberd_hooks:run(unset_presence_hook, jlib:nameprep(Server),
- [User, Server, Resource, Status]).
-
get_user_present_resources(LUser, LServer) ->
US = {LUser, LServer},
case catch mnesia:dirty_index_read(session, US, #session.us) of
@@ -385,28 +487,6 @@ get_user_present_resources(LUser, LServer) ->
S <- clean_session_list(Ss), is_integer(S#session.priority)]
end.
-dirty_get_sessions_list() ->
- mnesia:dirty_select(
- session,
- [{#session{usr = '$1', _ = '_'},
- [],
- ['$1']}]).
-
-dirty_get_my_sessions_list() ->
- mnesia:dirty_select(
- session,
- [{#session{sid = {'_', '$1'}, _ = '_'},
- [{'==', {node, '$1'}, node()}],
- ['$_']}]).
-
-get_vh_session_list(Server) ->
- LServer = jlib:nameprep(Server),
- mnesia:dirty_select(
- session,
- [{#session{usr = '$1', _ = '_'},
- [{'==', {element, 2, '$1'}, LServer}],
- ['$1']}]).
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -441,15 +521,6 @@ process_iq(From, To, Packet) ->
ok
end.
-register_iq_handler(Host, XMLNS, Module, Fun) ->
- ejabberd_sm ! {register_iq_handler, Host, XMLNS, Module, Fun}.
-
-register_iq_handler(Host, XMLNS, Module, Fun, Opts) ->
- ejabberd_sm ! {register_iq_handler, Host, XMLNS, Module, Fun, Opts}.
-
-unregister_iq_handler(Host, XMLNS) ->
- ejabberd_sm ! {unregister_iq_handler, Host, XMLNS}.
-
update_tables() ->
diff --git a/src/ejabberd_sup.erl b/src/ejabberd_sup.erl
index d58ec422f..1e6851dc2 100644
--- a/src/ejabberd_sup.erl
+++ b/src/ejabberd_sup.erl
@@ -68,6 +68,14 @@ init([]) ->
infinity,
supervisor,
[ejabberd_listener]},
+ ReceiverSupervisor =
+ {ejabberd_receiver_sup,
+ {ejabberd_tmp_sup, start_link,
+ [ejabberd_receiver_sup, ejabberd_receiver]},
+ permanent,
+ infinity,
+ supervisor,
+ [ejabberd_tmp_sup]},
C2SSupervisor =
{ejabberd_c2s_sup,
{ejabberd_tmp_sup, start_link, [ejabberd_c2s_sup, ejabberd_c2s]},
@@ -130,6 +138,7 @@ init([]) ->
SM,
S2S,
Local,
+ ReceiverSupervisor,
C2SSupervisor,
S2SInSupervisor,
S2SOutSupervisor,
diff --git a/src/ejabberd_update.erl b/src/ejabberd_update.erl
index 103b20509..a094bd2ce 100644
--- a/src/ejabberd_update.erl
+++ b/src/ejabberd_update.erl
@@ -95,11 +95,17 @@ update() ->
make_script(UpdatedBeams) ->
lists:map(
fun(Module) ->
- {ok, {Module, [{attributes, Attrs}]}} =
+ {ok, {Module, [{attributes, NewAttrs}]}} =
beam_lib:chunks(code:which(Module), [attributes]),
- case lists:keysearch(update_info, 1, Attrs) of
- {value, {_, [{update, Extra}]}} ->
- {update, Module, {advanced, Extra}};
+ CurAttrs = Module:module_info(attributes),
+ case lists:keysearch(update_info, 1, NewAttrs) of
+ {value, {_, [{update, _}]}} ->
+ case lists:keysearch(update_info, 1, CurAttrs) of
+ {value, {_, [{update, Extra}]}} ->
+ {update, Module, {advanced, Extra}};
+ false ->
+ {update, Module, {advanced, 0}}
+ end;
false ->
{load_module, Module}
end
diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl
index caed05000..f0c77f78c 100644
--- a/src/gen_iq_handler.erl
+++ b/src/gen_iq_handler.erl
@@ -1,7 +1,7 @@
%%%----------------------------------------------------------------------
%%% File : gen_iq_handler.erl
%%% Author : Alexey Shchepin <alexey@sevcom.net>
-%%% Purpose :
+%%% Purpose : IQ handler support
%%% Created : 22 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
%%% Id : $Id$
%%%----------------------------------------------------------------------
@@ -10,19 +10,35 @@
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
--export([start/0,
- start_link/3,
+-behaviour(gen_server).
+
+%% API
+-export([start_link/3,
add_iq_handler/6,
remove_iq_handler/3,
stop_iq_handler/3,
handle/7,
- process_iq/6,
- queue_init/3]).
+ process_iq/6]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2, code_change/3]).
-include("ejabberd.hrl").
-start() ->
- ok.
+-record(state, {host,
+ module,
+ function}).
+
+%%====================================================================
+%% API
+%%====================================================================
+%%--------------------------------------------------------------------
+%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
+%% Description: Starts the server
+%%--------------------------------------------------------------------
+start_link(Host, Module, Function) ->
+ gen_server:start_link(?MODULE, [Host, Module, Function], []).
add_iq_handler(Component, Host, NS, Module, Function, Type) ->
case Type of
@@ -40,10 +56,10 @@ add_iq_handler(Component, Host, NS, Module, Function, Type) ->
remove_iq_handler(Component, Host, NS) ->
Component:unregister_iq_handler(Host, NS).
-stop_iq_handler(Module, Function, Opts) ->
+stop_iq_handler(_Module, _Function, Opts) ->
case Opts of
{one_queue, Pid} ->
- exit(Pid, kill);
+ gen_server:call(Pid, stop);
_ ->
ok
end.
@@ -75,18 +91,76 @@ process_iq(_Host, Module, Function, From, To, IQ) ->
end
end.
-start_link(Host, Module, Function) ->
- {ok, proc_lib:spawn_link(?MODULE, queue_init, [Host, Module, Function])}.
+%%====================================================================
+%% gen_server callbacks
+%%====================================================================
-queue_init(Host, Module, Function) ->
- queue_loop(Host, Module, Function).
+%%--------------------------------------------------------------------
+%% Function: init(Args) -> {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%% Description: Initiates the server
+%%--------------------------------------------------------------------
+init([Host, Module, Function]) ->
+ {ok, #state{host = Host,
+ module = Module,
+ function = Function}}.
-% TODO: use gen_event
-queue_loop(Host, Module, Function) ->
- receive
- {process_iq, From, To, IQ} ->
- process_iq(Host, Module, Function, From, To, IQ),
- queue_loop(Host, Module, Function);
- _ ->
- queue_loop(Host, Module, Function)
- end.
+%%--------------------------------------------------------------------
+%% 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) ->
+ Reply = ok,
+ {stop, normal, Reply, 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({process_iq, From, To, IQ},
+ #state{host = Host,
+ module = Module,
+ function = Function} = State) ->
+ process_iq(Host, Module, Function, From, To, IQ),
+ {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) ->
+ 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
+%%--------------------------------------------------------------------
diff --git a/src/odbc/pg.sql b/src/odbc/pg.sql
index e8404b134..0db27d2c5 100644
--- a/src/odbc/pg.sql
+++ b/src/odbc/pg.sql
@@ -36,12 +36,12 @@ CREATE TABLE rostergroups (
CREATE INDEX pk_rosterg_user_jid ON rostergroups USING btree (username, jid);
-;; To update from previous table definition:
-; CREATE SEQUENCE spool_seq_seq;
-; ALTER TABLE spool ADD COLUMN seq integer;
-; ALTER TABLE spool ALTER COLUMN seq SET DEFAULT nextval('spool_seq_seq');
-; UPDATE spool SET seq = DEFAULT;
-; ALTER TABLE spool ALTER COLUMN seq SET NOT NULL;
+--- To update from previous table definition:
+-- CREATE SEQUENCE spool_seq_seq;
+-- ALTER TABLE spool ADD COLUMN seq integer;
+-- ALTER TABLE spool ALTER COLUMN seq SET DEFAULT nextval('spool_seq_seq');
+-- UPDATE spool SET seq = DEFAULT;
+-- ALTER TABLE spool ALTER COLUMN seq SET NOT NULL;
CREATE TABLE spool (
username text NOT NULL,