diff options
author | Alexey Shchepin <alexey@process-one.net> | 2006-02-03 03:28:15 +0000 |
---|---|---|
committer | Alexey Shchepin <alexey@process-one.net> | 2006-02-03 03:28:15 +0000 |
commit | dc57e75e8fcf5c5b741bbc65522bba047c0b2791 (patch) | |
tree | 440f3b0ab9c4217c1d5810e77821126e4990b903 /src/mod_irc | |
parent | --prefix option can now override the default install dir (EJAB-43) (diff) |
* src/web/ejabberd_http.erl: Authentication check moved to
ejabberd_web.erl
* src/web/ejabberd_web.erl: Likewise
* src/web/Makefile.in: Added ejabberd_http.hrl dependency
* src/web/ejabberd_http_poll.erl: Updated to use {active, once}
socket mode
* src/mod_irc/mod_irc.erl: Updated to use gen_server behaviour and
ejabberd supervision tree
* src/mod_irc/mod_irc_connection.erl: Likewise
SVN Revision: 498
Diffstat (limited to 'src/mod_irc')
-rw-r--r-- | src/mod_irc/mod_irc.erl | 173 | ||||
-rw-r--r-- | src/mod_irc/mod_irc_connection.erl | 12 |
2 files changed, 147 insertions, 38 deletions
diff --git a/src/mod_irc/mod_irc.erl b/src/mod_irc/mod_irc.erl index 1192df510..6c36a71b8 100644 --- a/src/mod_irc/mod_irc.erl +++ b/src/mod_irc/mod_irc.erl @@ -10,12 +10,20 @@ -author('alexey@sevcom.net'). -vsn('$Revision$ '). +-behaviour(gen_server). -behaviour(gen_mod). --export([start/2, init/2, stop/1, +%% API +-export([start_link/2, + start/2, + stop/1, closed_connection/3, get_user_and_encoding/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"). @@ -24,9 +32,51 @@ -record(irc_connection, {jid_server_host, pid}). -record(irc_custom, {us_host, data}). +-record(state, {host, server_host, access}). + -define(PROCNAME, ejabberd_mod_irc). +%%==================================================================== +%% 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_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). + +%%==================================================================== +%% gen_server callbacks +%%==================================================================== + +%%-------------------------------------------------------------------- +%% Function: init(Args) -> {ok, State} | +%% {ok, State, Timeout} | +%% ignore | +%% {stop, Reason} +%% Description: Initiates the server +%%-------------------------------------------------------------------- +init([Host, Opts]) -> iconv:start(), mnesia:create_table(irc_custom, [{disc_copies, [node()]}, @@ -34,38 +84,97 @@ start(Host, Opts) -> MyHost = gen_mod:get_opt(host, Opts, "irc." ++ Host), update_table(MyHost), Access = gen_mod:get_opt(access, Opts, all), - register(gen_mod:get_module_proc(Host, ?PROCNAME), - spawn(?MODULE, init, [MyHost, Access])). - -init(Host, Access) -> catch ets:new(irc_connection, [named_table, public, {keypos, #irc_connection.jid_server_host}]), - ejabberd_router:register_route(Host), - loop(Host, Access). - -loop(Host, Access) -> - receive - {route, From, To, Packet} -> - case catch do_route(Host, Access, From, To, Packet) of - {'EXIT', Reason} -> - ?ERROR_MSG("~p", [Reason]); - _ -> - ok - end, - loop(Host, Access); - stop -> - ejabberd_router:unregister_route(Host), - ok; + ejabberd_router:register_route(MyHost), + {ok, #state{host = MyHost, + server_host = Host, + access = Access}}. + +%%-------------------------------------------------------------------- +%% 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{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, Access) - end. - - -do_route(Host, Access, 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) -> + 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_irc_sup), + ChildSpec = + {Proc, + {ejabberd_tmp_sup, start_link, + [Proc, mod_irc_connection]}, + permanent, + infinity, + supervisor, + [ejabberd_tmp_sup]}, + supervisor:start_child(ejabberd_sup, ChildSpec). + +stop_supervisor(Host) -> + Proc = gen_mod:get_module_proc(Host, ejabberd_mod_irc_sup), + supervisor:terminate_child(ejabberd_sup, Proc), + supervisor:delete_child(ejabberd_sup, Proc). + +do_route(Host, ServerHost, Access, From, To, Packet) -> case acl:match_rule(Host, Access, From) of allow -> - do_route1(Host, From, To, Packet); + do_route1(Host, ServerHost, From, To, Packet); _ -> {xmlelement, _Name, Attrs, _Els} = Packet, Lang = xml:get_attr_s("xml:lang", Attrs), @@ -75,7 +184,7 @@ do_route(Host, Access, From, To, Packet) -> ejabberd_router:route(To, From, Err) end. -do_route1(Host, From, To, Packet) -> +do_route1(Host, ServerHost, From, To, Packet) -> #jid{user = ChanServ, resource = Resource} = To, {xmlelement, _Name, Attrs, _Els} = Packet, case ChanServ of @@ -132,7 +241,7 @@ do_route1(Host, From, To, Packet) -> {Username, Encoding} = get_user_and_encoding( Host, From, Server), {ok, Pid} = mod_irc_connection:start( - From, Host, Server, + From, Host, ServerHost, Server, Username, Encoding), ets:insert( irc_connection, @@ -174,12 +283,6 @@ do_route1(Host, From, To, Packet) -> end. -stop(Host) -> - Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - Proc ! stop, - {wait, Proc}. - - closed_connection(Host, From, Server) -> ets:delete(irc_connection, {From, Server, Host}). diff --git a/src/mod_irc/mod_irc_connection.erl b/src/mod_irc/mod_irc_connection.erl index 8343a6f92..869b2e864 100644 --- a/src/mod_irc/mod_irc_connection.erl +++ b/src/mod_irc/mod_irc_connection.erl @@ -13,7 +13,7 @@ -behaviour(gen_fsm). %% External exports --export([start/5, route_chan/4, route_nick/3]). +-export([start_link/5, start/6, route_chan/4, route_nick/3]). %% gen_fsm callbacks -export([init/1, @@ -47,8 +47,14 @@ %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- -start(From, Host, Server, Username, Encoding) -> - gen_fsm:start(?MODULE, [From, Host, Server, Username, Encoding], ?FSMOPTS). +start(From, Host, ServerHost, Server, Username, Encoding) -> + Supervisor = gen_mod:get_module_proc(ServerHost, ejabberd_mod_irc_sup), + supervisor:start_child( + Supervisor, [From, Host, Server, Username, Encoding]). + +start_link(From, Host, Server, Username, Encoding) -> + gen_fsm:start_link(?MODULE, [From, Host, Server, Username, Encoding], + ?FSMOPTS). %%%---------------------------------------------------------------------- %%% Callback functions from gen_fsm |