* src/ejabberd_c2s.erl: Use resend_offline_messages_hook to fetch
offline messages * src/mod_offline.erl: Likewise * src/mod_offline.erl: Added table locking in remove_old_messages/1 * src/ejabberd_sm.erl: Use offline_message_hook to store offline messages * src/mod_offline.erl: Likewise * src/ejabberd_hooks.erl: Hooks support * src/ejabberd_sup.erl: Added ejabberd_hooks * doc/guide.tex: Updated * src/ejabberd.cfg.example: Updated * src/ejabberd_c2s.erl: Changed TLS options (thanks to Sergei Golovan) SVN Revision: 255
This commit is contained in:
parent
0ef537cc6c
commit
357554265e
23
ChangeLog
23
ChangeLog
|
@ -1,3 +1,26 @@
|
|||
2004-08-08 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
* src/ejabberd_c2s.erl: Use resend_offline_messages_hook to fetch
|
||||
offline messages
|
||||
* src/mod_offline.erl: Likewise
|
||||
|
||||
* src/mod_offline.erl: Added table locking in
|
||||
remove_old_messages/1
|
||||
|
||||
* src/ejabberd_sm.erl: Use offline_message_hook to store offline
|
||||
messages
|
||||
* src/mod_offline.erl: Likewise
|
||||
|
||||
* src/ejabberd_hooks.erl: Hooks support
|
||||
* src/ejabberd_sup.erl: Added ejabberd_hooks
|
||||
|
||||
* doc/guide.tex: Updated
|
||||
|
||||
* src/ejabberd.cfg.example: Updated
|
||||
|
||||
* src/ejabberd_c2s.erl: Changed TLS options (thanks to Sergei
|
||||
Golovan)
|
||||
|
||||
2004-08-05 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
* src/aclocal.m4: Updated to check for openssl library (thanks to
|
||||
|
|
|
@ -142,7 +142,7 @@ Works on most of popular platforms: *nix (tested on Linux, FreeBSD and
|
|||
The misfeatures of <TT>ejabberd</TT> are:
|
||||
<UL><LI>
|
||||
No support for virtual domains
|
||||
<LI>No support for STARTTLS
|
||||
<LI>No support for authentification and STARTTLS in S2S connections
|
||||
</UL>
|
||||
<!--TOC section Installation-->
|
||||
|
||||
|
@ -164,7 +164,8 @@ To compile <TT>ejabberd</TT>, you will need the following packages:
|
|||
GNU Make;
|
||||
<LI>GCC;
|
||||
<LI>libexpat 1.95 or later;
|
||||
<LI>Erlang/OTP R8B or later.
|
||||
<LI>Erlang/OTP R8B or later;
|
||||
<LI>OpenSSL 0.9.6 or later (optional).
|
||||
</UL>
|
||||
<!--TOC subsubsection Windows-->
|
||||
|
||||
|
@ -473,8 +474,15 @@ The following options are defined:
|
|||
<DT><B><TT>{ip, IPAddress}</TT></B><DD> This option specifies which network interface to
|
||||
listen on. For example <CODE>{ip, {192, 168, 1, 1}}</CODE>.
|
||||
<DT><B><TT>inet6</TT></B><DD> Set up the socket for IPv6.
|
||||
<DT><B><TT>tls</TT></B><DD> This option specifies that STARTTLS extension is available on
|
||||
connections to this port. You should also set ``<CODE>certfile</CODE>'' option.
|
||||
<DT><B><TT>tls_from_start</TT></B><DD> Among with <TT>tls</TT> this option specifies that
|
||||
traffic on this port will be encrypted using SSL immediately after
|
||||
connecting.
|
||||
<DT><B><TT>ssl</TT></B><DD> This option specifies that traffic on this port will be
|
||||
encrypted using SSL. You should also set ``<CODE>certfile</CODE>'' option.
|
||||
encrypted using SSL. You should also set ``<CODE>certfile</CODE>'' option. It
|
||||
is recommended to use <TT>tls</TT> and <TT>tls_from_start</TT> options
|
||||
instead.
|
||||
<DT><B><TT>{certfile, Path}</TT></B><DD> Path to a file containing the SSL certificate.
|
||||
</DL>
|
||||
<DT><B><TT>ejabberd_s2s_in</TT></B><DD> This module serves incoming S2S connections.
|
||||
|
@ -495,7 +503,7 @@ The following additional options are defined for <TT>ejabberd_service</TT>
|
|||
<BR>
|
||||
The following options are defined:
|
||||
<DL COMPACT=compact><DT>
|
||||
<B><TT>http_poll</TT></B><DD> This option enables <A HREF="http://www.jabber.org/jeps/jep-0025.html">HTTP Polling</A> .
|
||||
<B><TT>http_poll</TT></B><DD> This option enables <A HREF="http://www.jabber.org/jeps/jep-0025.html">HTTP Polling</A>
|
||||
support. It is available then at <CODE>http://server:port/http-poll/</CODE>.<BR>
|
||||
<BR>
|
||||
<DT><B><TT>web_admin</TT></B><DD> This option enables web-based interface for <TT>ejabberd</TT>
|
||||
|
|
|
@ -126,7 +126,7 @@ The main features of \ejabberd{} are:
|
|||
The misfeatures of \ejabberd{} are:
|
||||
\begin{itemize}
|
||||
\item No support for virtual domains
|
||||
\item No support for STARTTLS
|
||||
\item No support for authentification and STARTTLS in S2S connections
|
||||
\end{itemize}
|
||||
|
||||
|
||||
|
@ -144,7 +144,8 @@ To compile \ejabberd{}, you will need the following packages:
|
|||
\item GNU Make;
|
||||
\item GCC;
|
||||
\item libexpat 1.95 or later;
|
||||
\item Erlang/OTP R8B or later.
|
||||
\item Erlang/OTP R8B or later;
|
||||
\item OpenSSL 0.9.6 or later (optional).
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{Windows}
|
||||
|
@ -285,8 +286,6 @@ But in this case \ejabberd{} can start to work slower.
|
|||
\subsection{Initial Configuration}
|
||||
\label{sec:initconfig}
|
||||
|
||||
%\verbatiminput{../src/ejabberd.cfg}
|
||||
|
||||
The configuration file is initially loaded the first time \ejabberd{} is
|
||||
executed, when it is parsed and stored in a database. Subsequently the
|
||||
configuration is loaded from the database and any commands in the configuration
|
||||
|
@ -477,8 +476,15 @@ Currently these modules are implemented:
|
|||
\titem{\{ip, IPAddress\}} This option specifies which network interface to
|
||||
listen on. For example \verb|{ip, {192, 168, 1, 1}}|.
|
||||
\titem{inet6} Set up the socket for IPv6.
|
||||
\titem{starttls} This option specifies that STARTTLS extension is available
|
||||
on connections to this port. You should also set ``\verb|certfile|''
|
||||
option.
|
||||
\titem{tls} This option specifies that traffic on this port will be
|
||||
encrypted using SSL immediately after connecting. You should also set
|
||||
``\verb|certfile|'' option.
|
||||
\titem{ssl} This option specifies that traffic on this port will be
|
||||
encrypted using SSL. You should also set ``\verb|certfile|'' option.
|
||||
encrypted using SSL. You should also set ``\verb|certfile|'' option. It
|
||||
is recommended to use \term{tls} option instead.
|
||||
\titem{\{certfile, Path\}} Path to a file containing the SSL certificate.
|
||||
\end{description}
|
||||
\titem{ejabberd\_s2s\_in} This module serves incoming S2S connections.
|
||||
|
@ -499,7 +505,7 @@ Currently these modules are implemented:
|
|||
|
||||
The following options are defined:
|
||||
\begin{description}
|
||||
\titem{http\_poll} This option enables \tjepref{0025}{HTTP Polling} .
|
||||
\titem{http\_poll} This option enables \tjepref{0025}{HTTP Polling}
|
||||
support. It is available then at \verb|http://server:port/http-poll/|.
|
||||
|
||||
\titem{web\_admin} This option enables web-based interface for \ejabberd{}
|
||||
|
|
|
@ -91,8 +91,13 @@
|
|||
|
||||
% Listened ports:
|
||||
{listen,
|
||||
[{5222, ejabberd_c2s, [{access, c2s}, {shaper, c2s_shaper}]},
|
||||
{5223, ejabberd_c2s, [{access, c2s}, ssl, {certfile, "./ssl.pem"}]},
|
||||
[{5222, ejabberd_c2s, [{access, c2s}, {shaper, c2s_shaper},
|
||||
starttls, {certfile, "./ssl.pem"}]},
|
||||
{5223, ejabberd_c2s, [{access, c2s},
|
||||
tls, {certfile, "./ssl.pem"}]},
|
||||
% Use these two lines instead if TLS support is not compiled
|
||||
%{5222, ejabberd_c2s, [{access, c2s}, {shaper, c2s_shaper}]},
|
||||
%{5223, ejabberd_c2s, [{access, c2s}, ssl, {certfile, "./ssl.pem"}]},
|
||||
{5269, ejabberd_s2s_in, [{shaper, s2s_shaper}]},
|
||||
{5280, ejabberd_http, [http_poll, web_admin]},
|
||||
{8888, ejabberd_service, [{access, all},
|
||||
|
|
|
@ -80,8 +80,6 @@
|
|||
|
||||
-define(INVALID_NS_ERR,
|
||||
xml:element_to_string(?SERR_INVALID_NAMESPACE)).
|
||||
%-define(INVALID_XML_ERR,
|
||||
% "<stream:error code='400'>Invalid XML</stream:error>").
|
||||
-define(INVALID_XML_ERR,
|
||||
xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)).
|
||||
|
||||
|
@ -118,8 +116,9 @@ init([{SockMod, Socket}, Opts]) ->
|
|||
{value, {_, S}} -> S;
|
||||
_ -> none
|
||||
end,
|
||||
TLS = lists:member(tls, Opts),
|
||||
TLSEnabled = lists:member(tls_from_start, Opts),
|
||||
StartTLS = lists:member(starttls, Opts),
|
||||
TLSEnabled = lists:member(tls, Opts),
|
||||
TLS = StartTLS orelse TLSEnabled,
|
||||
TLSOpts = lists:filter(fun({certfile, _}) -> true;
|
||||
(_) -> false
|
||||
end, Opts),
|
||||
|
@ -1387,9 +1386,8 @@ process_privacy_iq(From, To,
|
|||
|
||||
|
||||
resend_offline_messages(StateData) ->
|
||||
case catch mod_offline:pop_offline_messages(StateData#state.user) of
|
||||
{'EXIT', _Reason} ->
|
||||
ok;
|
||||
case ejabberd_hooks:run_fold(resend_offline_messages_hook, [],
|
||||
[StateData#state.user]) of
|
||||
Rs when list(Rs) ->
|
||||
lists:foreach(
|
||||
fun({route, From, To, {xmlelement, Name, Attrs, Els}}) ->
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
%%%----------------------------------------------------------------------
|
||||
%%% File : ejabberd_hooks.erl
|
||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Purpose : Manage hooks
|
||||
%%% Created : 8 Aug 2004 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(ejabberd_hooks).
|
||||
-author('alexey@sevcom.net').
|
||||
|
||||
-behaviour(gen_server).
|
||||
|
||||
%% External exports
|
||||
-export([start_link/0,
|
||||
add/4,
|
||||
delete/4,
|
||||
run/2,
|
||||
run_fold/3]).
|
||||
|
||||
%% gen_server callbacks
|
||||
-export([init/1,
|
||||
handle_call/3,
|
||||
handle_cast/2,
|
||||
code_change/3,
|
||||
handle_info/2,
|
||||
terminate/2]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
-record(state, {}).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% API
|
||||
%%%----------------------------------------------------------------------
|
||||
start_link() ->
|
||||
gen_server:start_link({local, ejabberd_hooks}, ejabberd_hooks, [], []).
|
||||
|
||||
add(Hook, Module, Function, Seq) ->
|
||||
gen_server:call(ejabberd_hooks, {add, Hook, Module, Function, Seq}).
|
||||
|
||||
delete(Hook, Module, Function, Seq) ->
|
||||
gen_server:call(ejabberd_hooks, {delete, Hook, Module, Function, Seq}).
|
||||
|
||||
run(Hook, Args) ->
|
||||
case ets:lookup(hooks, Hook) of
|
||||
[{_, Ls}] ->
|
||||
run1(Ls, Hook, Args);
|
||||
[] ->
|
||||
ok
|
||||
end.
|
||||
|
||||
run_fold(Hook, Val, Args) ->
|
||||
case ets:lookup(hooks, Hook) of
|
||||
[{_, Ls}] ->
|
||||
run_fold1(Ls, Hook, Val, Args);
|
||||
[] ->
|
||||
ok
|
||||
end.
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% Callback functions from gen_server
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
%%----------------------------------------------------------------------
|
||||
%% Func: init/1
|
||||
%% Returns: {ok, State} |
|
||||
%% {ok, State, Timeout} |
|
||||
%% ignore |
|
||||
%% {stop, Reason}
|
||||
%%----------------------------------------------------------------------
|
||||
init([]) ->
|
||||
ets:new(hooks, [named_table]),
|
||||
{ok, #state{}}.
|
||||
|
||||
%%----------------------------------------------------------------------
|
||||
%% Func: handle_call/3
|
||||
%% Returns: {reply, Reply, State} |
|
||||
%% {reply, Reply, State, Timeout} |
|
||||
%% {noreply, State} |
|
||||
%% {noreply, State, Timeout} |
|
||||
%% {stop, Reason, Reply, State} | (terminate/2 is called)
|
||||
%% {stop, Reason, State} (terminate/2 is called)
|
||||
%%----------------------------------------------------------------------
|
||||
handle_call({add, Hook, Module, Function, Seq}, From, State) ->
|
||||
Reply = case ets:lookup(hooks, Hook) of
|
||||
[{_, Ls}] ->
|
||||
El = {Seq, Module, Function},
|
||||
case lists:member(El, Ls) of
|
||||
true ->
|
||||
ok;
|
||||
false ->
|
||||
NewLs = lists:merge(Ls, [El]),
|
||||
ets:insert(hooks, {Hook, NewLs}),
|
||||
ok
|
||||
end;
|
||||
[] ->
|
||||
NewLs = [{Seq, Module, Function}],
|
||||
ets:insert(hooks, {Hook, NewLs}),
|
||||
ok
|
||||
end,
|
||||
{reply, Reply, State};
|
||||
handle_call({delete, Hook, Module, Function, Seq}, From, State) ->
|
||||
Reply = case ets:lookup(hooks, Hook) of
|
||||
[{_, Ls}] ->
|
||||
NewLs = lists:delete({Seq, Module, Function}, Ls),
|
||||
ets:insert(hooks, {Hook, NewLs}),
|
||||
ok;
|
||||
[] ->
|
||||
ok
|
||||
end,
|
||||
{reply, Reply, State};
|
||||
handle_call(Request, From, State) ->
|
||||
Reply = ok,
|
||||
{reply, Reply, State}.
|
||||
|
||||
%%----------------------------------------------------------------------
|
||||
%% Func: handle_cast/2
|
||||
%% Returns: {noreply, State} |
|
||||
%% {noreply, State, Timeout} |
|
||||
%% {stop, Reason, State} (terminate/2 is called)
|
||||
%%----------------------------------------------------------------------
|
||||
handle_cast(Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
%%----------------------------------------------------------------------
|
||||
%% Func: handle_info/2
|
||||
%% Returns: {noreply, State} |
|
||||
%% {noreply, State, Timeout} |
|
||||
%% {stop, Reason, State} (terminate/2 is called)
|
||||
%%----------------------------------------------------------------------
|
||||
handle_info(Info, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
%%----------------------------------------------------------------------
|
||||
%% Func: terminate/2
|
||||
%% Purpose: Shutdown the server
|
||||
%% Returns: any (ignored by gen_server)
|
||||
%%----------------------------------------------------------------------
|
||||
terminate(Reason, State) ->
|
||||
ok.
|
||||
|
||||
|
||||
code_change(_OldVsn, State, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% Internal functions
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
run1([], Hook, Args) ->
|
||||
ok;
|
||||
run1([{_Seq, Module, Function} | Ls], Hook, Args) ->
|
||||
case catch apply(Module, Function, Args) of
|
||||
{'EXIT', Reason} ->
|
||||
?ERROR_MSG("~p~nrunning hook: ~p",
|
||||
[Reason, {Hook, Args}]),
|
||||
run1(Ls, Hook, Args);
|
||||
stop ->
|
||||
ok;
|
||||
_ ->
|
||||
run1(Ls, Hook, Args)
|
||||
end.
|
||||
|
||||
|
||||
run_fold1([], Hook, Val, Args) ->
|
||||
Val;
|
||||
run_fold1([{_Seq, Module, Function} | Ls], Hook, Val, Args) ->
|
||||
case catch apply(Module, Function, [Val | Args]) of
|
||||
{'EXIT', Reason} ->
|
||||
?ERROR_MSG("~p~nrunning hook: ~p",
|
||||
[Reason, {Hook, Args}]),
|
||||
run_fold1(Ls, Hook, Val, Args);
|
||||
stop ->
|
||||
stopped;
|
||||
{stop, NewVal} ->
|
||||
NewVal;
|
||||
NewVal ->
|
||||
run_fold1(Ls, Hook, NewVal, Args)
|
||||
end.
|
||||
|
||||
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
-vsn('$Revision$ ').
|
||||
|
||||
-export([start_link/0, init/0, open_session/2, close_session/2,
|
||||
bounce_offline_message/3,
|
||||
get_user_resources/1,
|
||||
set_presence/3,
|
||||
unset_presence/3,
|
||||
|
@ -44,6 +45,8 @@ init() ->
|
|||
mnesia:add_table_index(presence, user),
|
||||
mnesia:subscribe(system),
|
||||
ets:new(sm_iqtable, [named_table]),
|
||||
ejabberd_hooks:add(offline_message_hook,
|
||||
ejabberd_sm, bounce_offline_message, 100),
|
||||
loop().
|
||||
|
||||
loop() ->
|
||||
|
@ -263,18 +266,11 @@ route_message(From, To, Packet) ->
|
|||
_ ->
|
||||
case ejabberd_auth:is_user_exists(LUser) of
|
||||
true ->
|
||||
case catch mod_offline:store_packet(
|
||||
From, To, Packet) of
|
||||
{'EXIT', _} ->
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERR_SERVICE_UNAVAILABLE),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
_ ->
|
||||
ok
|
||||
end;
|
||||
ejabberd_hooks:run(offline_message_hook,
|
||||
[From, To, Packet]);
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERR_ITEM_NOT_FOUND),
|
||||
Packet, ?ERR_SERVICE_UNAVAILABLE),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end
|
||||
end;
|
||||
|
@ -291,6 +287,10 @@ 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.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
|
|
|
@ -19,36 +19,48 @@ start_link() ->
|
|||
|
||||
|
||||
init([]) ->
|
||||
Router = {ejabberd_router,
|
||||
{ejabberd_router, start_link, []},
|
||||
permanent,
|
||||
brutal_kill,
|
||||
worker,
|
||||
[ejabberd_router]},
|
||||
SM = {ejabberd_sm,
|
||||
{ejabberd_sm, start_link, []},
|
||||
permanent,
|
||||
brutal_kill,
|
||||
worker,
|
||||
[ejabberd_sm]},
|
||||
S2S = {ejabberd_s2s,
|
||||
{ejabberd_s2s, start_link, []},
|
||||
permanent,
|
||||
brutal_kill,
|
||||
worker,
|
||||
[ejabberd_s2s]},
|
||||
Local = {ejabberd_local,
|
||||
{ejabberd_local, start_link, []},
|
||||
permanent,
|
||||
brutal_kill,
|
||||
worker,
|
||||
[ejabberd_local]},
|
||||
Listener = {ejabberd_listener,
|
||||
{ejabberd_listener, start_link, []},
|
||||
permanent,
|
||||
infinity,
|
||||
supervisor,
|
||||
[ejabberd_listener]},
|
||||
Hooks =
|
||||
{ejabberd_hooks,
|
||||
{ejabberd_hooks, start_link, []},
|
||||
permanent,
|
||||
brutal_kill,
|
||||
worker,
|
||||
[ejabberd_hooks]},
|
||||
Router =
|
||||
{ejabberd_router,
|
||||
{ejabberd_router, start_link, []},
|
||||
permanent,
|
||||
brutal_kill,
|
||||
worker,
|
||||
[ejabberd_router]},
|
||||
SM =
|
||||
{ejabberd_sm,
|
||||
{ejabberd_sm, start_link, []},
|
||||
permanent,
|
||||
brutal_kill,
|
||||
worker,
|
||||
[ejabberd_sm]},
|
||||
S2S =
|
||||
{ejabberd_s2s,
|
||||
{ejabberd_s2s, start_link, []},
|
||||
permanent,
|
||||
brutal_kill,
|
||||
worker,
|
||||
[ejabberd_s2s]},
|
||||
Local =
|
||||
{ejabberd_local,
|
||||
{ejabberd_local, start_link, []},
|
||||
permanent,
|
||||
brutal_kill,
|
||||
worker,
|
||||
[ejabberd_local]},
|
||||
Listener =
|
||||
{ejabberd_listener,
|
||||
{ejabberd_listener, start_link, []},
|
||||
permanent,
|
||||
infinity,
|
||||
supervisor,
|
||||
[ejabberd_listener]},
|
||||
StringPrep =
|
||||
{stringprep,
|
||||
{stringprep, start_link, []},
|
||||
|
@ -112,7 +124,11 @@ init([]) ->
|
|||
supervisor,
|
||||
[ejabberd_tmp_sup]},
|
||||
{ok, {{one_for_one, 10, 1},
|
||||
[Router, SM, S2S, Local,
|
||||
[Hooks,
|
||||
Router,
|
||||
SM,
|
||||
S2S,
|
||||
Local,
|
||||
StringPrep,
|
||||
C2SSupervisor,
|
||||
S2SInSupervisor,
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
stop/0,
|
||||
store_packet/3,
|
||||
resend_offline_messages/1,
|
||||
pop_offline_messages/1,
|
||||
pop_offline_messages/2,
|
||||
remove_old_messages/1,
|
||||
remove_user/1]).
|
||||
|
||||
|
@ -31,6 +31,10 @@ start(_) ->
|
|||
[{disc_only_copies, [node()]},
|
||||
{type, bag},
|
||||
{attributes, record_info(fields, offline_msg)}]),
|
||||
ejabberd_hooks:add(offline_message_hook,
|
||||
?MODULE, store_packet, 50),
|
||||
ejabberd_hooks:add(resend_offline_messages_hook,
|
||||
?MODULE, pop_offline_messages, 50),
|
||||
register(?PROCNAME, spawn(?MODULE, init, [])).
|
||||
|
||||
init() ->
|
||||
|
@ -61,23 +65,31 @@ receive_all(Msgs) ->
|
|||
|
||||
|
||||
stop() ->
|
||||
ejabberd_hooks:delete(offline_message_hook,
|
||||
?MODULE, store_packet, 50),
|
||||
ejabberd_hooks:delete(resend_offline_messages_hook,
|
||||
?MODULE, pop_offline_messages, 50),
|
||||
exit(whereis(?PROCNAME), stop),
|
||||
ok.
|
||||
|
||||
store_packet(From, To, Packet) ->
|
||||
true = is_process_alive(whereis(?PROCNAME)),
|
||||
Type = xml:get_tag_attr_s("type", Packet),
|
||||
true = Type /= "error" andalso Type /= "groupchat",
|
||||
case check_event(From, To, Packet) of
|
||||
if
|
||||
(Type /= "error") and (Type /= "groupchat") ->
|
||||
case check_event(From, To, Packet) of
|
||||
true ->
|
||||
#jid{luser = LUser} = To,
|
||||
TimeStamp = now(),
|
||||
?PROCNAME ! #offline_msg{user = LUser,
|
||||
timestamp = TimeStamp,
|
||||
from = From,
|
||||
to = To,
|
||||
packet = Packet},
|
||||
stop;
|
||||
_ ->
|
||||
ok
|
||||
end;
|
||||
true ->
|
||||
#jid{luser = LUser} = To,
|
||||
TimeStamp = now(),
|
||||
?PROCNAME ! #offline_msg{user = LUser,
|
||||
timestamp = TimeStamp,
|
||||
from = From,
|
||||
to = To,
|
||||
packet = Packet};
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
|
@ -154,7 +166,7 @@ resend_offline_messages(User) ->
|
|||
ok
|
||||
end.
|
||||
|
||||
pop_offline_messages(User) ->
|
||||
pop_offline_messages(Ls, User) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
F = fun() ->
|
||||
Rs = mnesia:wread({offline_msg, LUser}),
|
||||
|
@ -175,9 +187,9 @@ pop_offline_messages(User) ->
|
|||
calendar:now_to_universal_time(
|
||||
R#offline_msg.timestamp))]}}
|
||||
end,
|
||||
lists:keysort(#offline_msg.timestamp, Rs));
|
||||
Ls ++ lists:keysort(#offline_msg.timestamp, Rs));
|
||||
_ ->
|
||||
[]
|
||||
Ls
|
||||
end.
|
||||
|
||||
remove_old_messages(Days) ->
|
||||
|
@ -187,6 +199,7 @@ remove_old_messages(Days) ->
|
|||
Secs1 = S rem 1000000,
|
||||
TimeStamp = {MegaSecs1, Secs1, 0},
|
||||
F = fun() ->
|
||||
mnesia:write_lock_table(offline_msg),
|
||||
mnesia:foldl(
|
||||
fun(#offline_msg{timestamp = TS} = Rec, _Acc)
|
||||
when TS < TimeStamp ->
|
||||
|
|
Loading…
Reference in New Issue