aboutsummaryrefslogtreecommitdiff
path: root/src/mod_irc
diff options
context:
space:
mode:
authorAlexey Shchepin <alexey@process-one.net>2006-02-03 03:28:15 +0000
committerAlexey Shchepin <alexey@process-one.net>2006-02-03 03:28:15 +0000
commitdc57e75e8fcf5c5b741bbc65522bba047c0b2791 (patch)
tree440f3b0ab9c4217c1d5810e77821126e4990b903 /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.erl173
-rw-r--r--src/mod_irc/mod_irc_connection.erl12
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