* src/ejabberd_c2s.erl: Bugfix in resend_offline_messages/1
* src/mod_announce.erl: New module to manage announce messages (thanks to Sergei Golovan) * src/ejabberd_local.erl: Moved processing of announce messages to mod_announce (thanks to Sergei Golovan) * src/ejabberd_c2s.erl: Added several hooks * src/ejabberd_hooks.erl: Fixed run_fold (thanks to Sergei Golovan) * src/ejabberd.cfg.example: Updated (thanks to Sergei Golovan) * doc/guide.tex: Updated (thanks to Sergei Golovan) SVN Revision: 256
This commit is contained in:
parent
357554265e
commit
d77a936b32
19
ChangeLog
19
ChangeLog
|
@ -1,3 +1,22 @@
|
|||
2004-08-12 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
* src/ejabberd_c2s.erl: Bugfix in resend_offline_messages/1
|
||||
|
||||
* src/mod_announce.erl: New module to manage announce messages
|
||||
(thanks to Sergei Golovan)
|
||||
|
||||
* src/ejabberd_local.erl: Moved processing of announce messages to
|
||||
mod_announce (thanks to Sergei Golovan)
|
||||
|
||||
* src/ejabberd_c2s.erl: Added several hooks
|
||||
|
||||
* src/ejabberd_hooks.erl: Fixed run_fold (thanks to Sergei
|
||||
Golovan)
|
||||
|
||||
* src/ejabberd.cfg.example: Updated (thanks to Sergei Golovan)
|
||||
|
||||
* doc/guide.tex: Updated (thanks to Sergei Golovan)
|
||||
|
||||
2004-08-08 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
* src/ejabberd_c2s.erl: Use resend_offline_messages_hook to fetch
|
||||
|
|
107
doc/guide.html
107
doc/guide.html
|
@ -85,24 +85,25 @@
|
|||
<A HREF="#htoc30">A.1.1 Option <TT>iqdisc</TT></A>
|
||||
<LI><A HREF="#htoc31">A.1.2 Option <TT>host</TT></A>
|
||||
</UL>
|
||||
<LI><A HREF="#htoc32">A.2 <TT>mod_configure</TT></A>
|
||||
<LI><A HREF="#htoc33">A.3 <TT>mod_disco</TT></A>
|
||||
<LI><A HREF="#htoc34">A.4 <TT>mod_echo</TT></A>
|
||||
<LI><A HREF="#htoc35">A.5 <TT>mod_irc</TT></A>
|
||||
<LI><A HREF="#htoc36">A.6 <TT>mod_last</TT></A>
|
||||
<LI><A HREF="#htoc37">A.7 <TT>mod_muc</TT></A>
|
||||
<LI><A HREF="#htoc38">A.8 <TT>mod_offline</TT></A>
|
||||
<LI><A HREF="#htoc39">A.9 <TT>mod_privacy</TT></A>
|
||||
<LI><A HREF="#htoc40">A.10 <TT>mod_private</TT></A>
|
||||
<LI><A HREF="#htoc41">A.11 <TT>mod_pubsub</TT></A>
|
||||
<LI><A HREF="#htoc42">A.12 <TT>mod_register</TT></A>
|
||||
<LI><A HREF="#htoc43">A.13 <TT>mod_roster</TT></A>
|
||||
<LI><A HREF="#htoc44">A.14 <TT>mod_stats</TT></A>
|
||||
<LI><A HREF="#htoc45">A.15 <TT>mod_time</TT></A>
|
||||
<LI><A HREF="#htoc46">A.16 <TT>mod_vcard</TT></A>
|
||||
<LI><A HREF="#htoc47">A.17 <TT>mod_version</TT></A>
|
||||
<LI><A HREF="#htoc32">A.2 <TT>mod_announce</TT></A>
|
||||
<LI><A HREF="#htoc33">A.3 <TT>mod_configure</TT></A>
|
||||
<LI><A HREF="#htoc34">A.4 <TT>mod_disco</TT></A>
|
||||
<LI><A HREF="#htoc35">A.5 <TT>mod_echo</TT></A>
|
||||
<LI><A HREF="#htoc36">A.6 <TT>mod_irc</TT></A>
|
||||
<LI><A HREF="#htoc37">A.7 <TT>mod_last</TT></A>
|
||||
<LI><A HREF="#htoc38">A.8 <TT>mod_muc</TT></A>
|
||||
<LI><A HREF="#htoc39">A.9 <TT>mod_offline</TT></A>
|
||||
<LI><A HREF="#htoc40">A.10 <TT>mod_privacy</TT></A>
|
||||
<LI><A HREF="#htoc41">A.11 <TT>mod_private</TT></A>
|
||||
<LI><A HREF="#htoc42">A.12 <TT>mod_pubsub</TT></A>
|
||||
<LI><A HREF="#htoc43">A.13 <TT>mod_register</TT></A>
|
||||
<LI><A HREF="#htoc44">A.14 <TT>mod_roster</TT></A>
|
||||
<LI><A HREF="#htoc45">A.15 <TT>mod_stats</TT></A>
|
||||
<LI><A HREF="#htoc46">A.16 <TT>mod_time</TT></A>
|
||||
<LI><A HREF="#htoc47">A.17 <TT>mod_vcard</TT></A>
|
||||
<LI><A HREF="#htoc48">A.18 <TT>mod_version</TT></A>
|
||||
</UL>
|
||||
<LI><A HREF="#htoc48">B I18n/L10n</A>
|
||||
<LI><A HREF="#htoc49">B I18n/L10n</A>
|
||||
</UL>
|
||||
|
||||
<!--TOC section Introduction-->
|
||||
|
@ -474,15 +475,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>starttls</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</TT></B><DD> This option specifies that traffic on this port will be
|
||||
encrypted using SSL immediately after connecting. You should also set
|
||||
``<CODE>certfile</CODE>'' option.
|
||||
<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. It
|
||||
is recommended to use <TT>tls</TT> and <TT>tls_from_start</TT> options
|
||||
instead.
|
||||
is recommended to use <TT>tls</TT> option 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.
|
||||
|
@ -818,9 +819,33 @@ Example:
|
|||
...
|
||||
]}.
|
||||
</PRE>
|
||||
<!--TOC subsection <TT>mod_announce</TT>-->
|
||||
|
||||
<H3><A NAME="htoc32">A.2</A> <TT>mod_announce</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:modannounce"></A>
|
||||
This module adds support for broadcast announce messages and MOTD.<BR>
|
||||
<BR>
|
||||
Options:
|
||||
<DL COMPACT=compact><DT>
|
||||
<B><TT>access</TT></B><DD> Specifies who is allowed to send announce messages
|
||||
and set MOTD (default value is <TT>none</TT>).
|
||||
</DL>
|
||||
Example:
|
||||
<PRE>
|
||||
% Only admins can send announcement messages:
|
||||
{access, announce, [{allow, admin}]}.
|
||||
|
||||
{modules,
|
||||
[
|
||||
...
|
||||
{mod_announce, [{access, announce}]},
|
||||
...
|
||||
]}.
|
||||
</PRE>
|
||||
<!--TOC subsection <TT>mod_configure</TT>-->
|
||||
|
||||
<H3><A NAME="htoc32">A.2</A> <TT>mod_configure</TT></H3><!--SEC END -->
|
||||
<H3><A NAME="htoc33">A.3</A> <TT>mod_configure</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:modconfigure"></A>
|
||||
Options:
|
||||
|
@ -830,7 +855,7 @@ discipline (see <A HREF="#sec:modiqdiscoption">A.1.1</A>).
|
|||
</DL>
|
||||
<!--TOC subsection <TT>mod_disco</TT>-->
|
||||
|
||||
<H3><A NAME="htoc33">A.3</A> <TT>mod_disco</TT></H3><!--SEC END -->
|
||||
<H3><A NAME="htoc34">A.4</A> <TT>mod_disco</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:moddisco"></A>
|
||||
This module adds support for <A HREF="http://www.jabber.org/jeps/jep-0030.html">JEP-0030</A> (Service Discovery).<BR>
|
||||
|
@ -855,7 +880,7 @@ Example:
|
|||
</PRE>
|
||||
<!--TOC subsection <TT>mod_echo</TT>-->
|
||||
|
||||
<H3><A NAME="htoc34">A.4</A> <TT>mod_echo</TT></H3><!--SEC END -->
|
||||
<H3><A NAME="htoc35">A.5</A> <TT>mod_echo</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:modecho"></A>
|
||||
This module acts as a service and simply returns to sender any Jabber packet. Module may be
|
||||
|
@ -869,7 +894,7 @@ then prefix <TT>echo.</TT> is added to main <TT>ejabberd</TT> hostname.
|
|||
</DL>
|
||||
<!--TOC subsection <TT>mod_irc</TT>-->
|
||||
|
||||
<H3><A NAME="htoc35">A.5</A> <TT>mod_irc</TT></H3><!--SEC END -->
|
||||
<H3><A NAME="htoc36">A.6</A> <TT>mod_irc</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:modirc"></A>
|
||||
This module implements IRC transport.<BR>
|
||||
|
@ -892,7 +917,7 @@ Example:
|
|||
</PRE>
|
||||
<!--TOC subsection <TT>mod_last</TT>-->
|
||||
|
||||
<H3><A NAME="htoc36">A.6</A> <TT>mod_last</TT></H3><!--SEC END -->
|
||||
<H3><A NAME="htoc37">A.7</A> <TT>mod_last</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:modlast"></A>
|
||||
This module adds support for <A HREF="http://www.jabber.org/jeps/jep-0012.html">JEP-0012</A> (Last Activity)<BR>
|
||||
|
@ -904,7 +929,7 @@ discipline (see <A HREF="#sec:modiqdiscoption">A.1.1</A>).
|
|||
</DL>
|
||||
<!--TOC subsection <TT>mod_muc</TT>-->
|
||||
|
||||
<H3><A NAME="htoc37">A.7</A> <TT>mod_muc</TT></H3><!--SEC END -->
|
||||
<H3><A NAME="htoc38">A.8</A> <TT>mod_muc</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:modmuc"></A>
|
||||
This module implements <A HREF="http://www.jabber.org/jeps/jep-0045.html">JEP-0045</A> (Multi-User Chat) service.<BR>
|
||||
|
@ -939,14 +964,14 @@ Example:
|
|||
</PRE>
|
||||
<!--TOC subsection <TT>mod_offline</TT>-->
|
||||
|
||||
<H3><A NAME="htoc38">A.8</A> <TT>mod_offline</TT></H3><!--SEC END -->
|
||||
<H3><A NAME="htoc39">A.9</A> <TT>mod_offline</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:modoffline"></A>
|
||||
This module implements offline message storage.<BR>
|
||||
<BR>
|
||||
<!--TOC subsection <TT>mod_privacy</TT>-->
|
||||
|
||||
<H3><A NAME="htoc39">A.9</A> <TT>mod_privacy</TT></H3><!--SEC END -->
|
||||
<H3><A NAME="htoc40">A.10</A> <TT>mod_privacy</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:modprivacy"></A>
|
||||
This module implements Privacy Rules as defined in XMPP IM
|
||||
|
@ -959,7 +984,7 @@ discipline (see <A HREF="#sec:modiqdiscoption">A.1.1</A>).
|
|||
</DL>
|
||||
<!--TOC subsection <TT>mod_private</TT>-->
|
||||
|
||||
<H3><A NAME="htoc40">A.10</A> <TT>mod_private</TT></H3><!--SEC END -->
|
||||
<H3><A NAME="htoc41">A.11</A> <TT>mod_private</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:modprivate"></A>
|
||||
This module adds support of <A HREF="http://www.jabber.org/jeps/jep-0049.html">JEP-0049</A> (Private XML Storage).<BR>
|
||||
|
@ -971,7 +996,7 @@ discipline (see <A HREF="#sec:modiqdiscoption">A.1.1</A>).
|
|||
</DL>
|
||||
<!--TOC subsection <TT>mod_pubsub</TT>-->
|
||||
|
||||
<H3><A NAME="htoc41">A.11</A> <TT>mod_pubsub</TT></H3><!--SEC END -->
|
||||
<H3><A NAME="htoc42">A.12</A> <TT>mod_pubsub</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:modpubsub"></A>
|
||||
This module implements <A HREF="http://www.jabber.org/jeps/jep-0060.html">JEP-0060</A> (Publish-Subscribe Service).<BR>
|
||||
|
@ -996,7 +1021,7 @@ Example:
|
|||
</PRE>
|
||||
<!--TOC subsection <TT>mod_register</TT>-->
|
||||
|
||||
<H3><A NAME="htoc42">A.12</A> <TT>mod_register</TT></H3><!--SEC END -->
|
||||
<H3><A NAME="htoc43">A.13</A> <TT>mod_register</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:modregister"></A>
|
||||
This module adds support for <A HREF="http://www.jabber.org/jeps/jep-0077.html">JEP-0077</A> (In-Band Registration).<BR>
|
||||
|
@ -1029,7 +1054,7 @@ Example:
|
|||
</PRE>
|
||||
<!--TOC subsection <TT>mod_roster</TT>-->
|
||||
|
||||
<H3><A NAME="htoc43">A.13</A> <TT>mod_roster</TT></H3><!--SEC END -->
|
||||
<H3><A NAME="htoc44">A.14</A> <TT>mod_roster</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:modroster"></A>
|
||||
This module implements roster management.<BR>
|
||||
|
@ -1041,7 +1066,7 @@ discipline (see <A HREF="#sec:modiqdiscoption">A.1.1</A>).
|
|||
</DL>
|
||||
<!--TOC subsection <TT>mod_stats</TT>-->
|
||||
|
||||
<H3><A NAME="htoc44">A.14</A> <TT>mod_stats</TT></H3><!--SEC END -->
|
||||
<H3><A NAME="htoc45">A.15</A> <TT>mod_stats</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:modstats"></A>
|
||||
This module adds support for <A HREF="http://www.jabber.org/jeps/jep-0039.html">JEP-0039</A> (Statistics Gathering).<BR>
|
||||
|
@ -1055,7 +1080,7 @@ TBD about access.<BR>
|
|||
<BR>
|
||||
<!--TOC subsection <TT>mod_time</TT>-->
|
||||
|
||||
<H3><A NAME="htoc45">A.15</A> <TT>mod_time</TT></H3><!--SEC END -->
|
||||
<H3><A NAME="htoc46">A.16</A> <TT>mod_time</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:modtime"></A>
|
||||
This module answers UTC time on <TT>jabber:iq:time</TT> queries.<BR>
|
||||
|
@ -1067,7 +1092,7 @@ discipline (see <A HREF="#sec:modiqdiscoption">A.1.1</A>).
|
|||
</DL>
|
||||
<!--TOC subsection <TT>mod_vcard</TT>-->
|
||||
|
||||
<H3><A NAME="htoc46">A.16</A> <TT>mod_vcard</TT></H3><!--SEC END -->
|
||||
<H3><A NAME="htoc47">A.17</A> <TT>mod_vcard</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:modvcard"></A>
|
||||
This module implements simple Jabber User Directory (based on user vCards)
|
||||
|
@ -1095,7 +1120,7 @@ Example:
|
|||
</PRE>
|
||||
<!--TOC subsection <TT>mod_version</TT>-->
|
||||
|
||||
<H3><A NAME="htoc47">A.17</A> <TT>mod_version</TT></H3><!--SEC END -->
|
||||
<H3><A NAME="htoc48">A.18</A> <TT>mod_version</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:modversion"></A>
|
||||
This module answers <TT>ejabberd</TT> version on <TT>jabber:iq:version</TT> queries.<BR>
|
||||
|
@ -1107,7 +1132,7 @@ discipline (see <A HREF="#sec:modiqdiscoption">A.1.1</A>).
|
|||
</DL>
|
||||
<!--TOC section I18n/L10n-->
|
||||
|
||||
<H2><A NAME="htoc48">B</A> I18n/L10n</H2><!--SEC END -->
|
||||
<H2><A NAME="htoc49">B</A> I18n/L10n</H2><!--SEC END -->
|
||||
|
||||
<A NAME="sec:i18nl10n"></A>
|
||||
All built-in modules support <TT>xml:lang</TT> attribute inside IQ queries.
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
\newcommand{\Jabber}{Jabber}
|
||||
|
||||
\newcommand{\module}[1]{\texttt{#1}}
|
||||
\newcommand{\modannounce}{\module{mod\_announce}}
|
||||
\newcommand{\modconfigure}{\module{mod\_configure}}
|
||||
\newcommand{\moddisco}{\module{mod\_disco}}
|
||||
\newcommand{\modirc}{\module{mod\_irc}}
|
||||
|
@ -812,6 +813,31 @@ Example:
|
|||
\end{verbatim}
|
||||
|
||||
|
||||
\subsection{\modannounce{}}
|
||||
\label{sec:modannounce}
|
||||
|
||||
This module adds support for broadcast announce messages and MOTD.
|
||||
|
||||
Options:
|
||||
\begin{description}
|
||||
\titem{access} Specifies who is allowed to send announce messages
|
||||
and set MOTD (default value is \term{none}).
|
||||
\end{description}
|
||||
|
||||
Example:
|
||||
\begin{verbatim}
|
||||
% Only admins can send announcement messages:
|
||||
{access, announce, [{allow, admin}]}.
|
||||
|
||||
{modules,
|
||||
[
|
||||
...
|
||||
{mod_announce, [{access, announce}]},
|
||||
...
|
||||
]}.
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
\subsection{\modconfigure{}}
|
||||
\label{sec:modconfigure}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
|
|||
AuthzId = xml:get_attr_s("authzid", KeyVals),
|
||||
case ejabberd_auth:get_password(UserName) of
|
||||
false ->
|
||||
{error, "no-user"};
|
||||
{error, "not-authorized"};
|
||||
Passwd ->
|
||||
Response = response(KeyVals, UserName, Passwd,
|
||||
Nonce, AuthzId, "AUTHENTICATE"),
|
||||
|
@ -66,7 +66,7 @@ mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
|
|||
username = UserName,
|
||||
authzid = AuthzId}};
|
||||
_ ->
|
||||
{error, "bad-auth"}
|
||||
{error, "not-authorized"}
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
|
|
@ -121,6 +121,7 @@
|
|||
{mod_stats, []},
|
||||
{mod_vcard, []},
|
||||
{mod_offline, []},
|
||||
{mod_announce, [{access, announce}]},
|
||||
{mod_echo, [{host, "echo.localhost"}]},
|
||||
{mod_private, []},
|
||||
{mod_irc, []},
|
||||
|
|
|
@ -673,12 +673,17 @@ session_established({xmlstreamelement, El}, StateData) ->
|
|||
process_privacy_iq(
|
||||
FromJID, ToJID, IQ, StateData);
|
||||
_ ->
|
||||
ejabberd_hooks:run(
|
||||
user_send_packet,
|
||||
[FromJID, ToJID, NewEl]),
|
||||
ejabberd_router:route(
|
||||
FromJID, ToJID, NewEl),
|
||||
StateData
|
||||
end
|
||||
end;
|
||||
"message" ->
|
||||
ejabberd_hooks:run(user_send_packet,
|
||||
[FromJID, ToJID, NewEl]),
|
||||
ejabberd_router:route(FromJID, ToJID, NewEl),
|
||||
StateData;
|
||||
_ ->
|
||||
|
@ -882,8 +887,11 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
|
|||
Attrs2 = jlib:replace_from_to_attrs(jlib:jid_to_string(From),
|
||||
jlib:jid_to_string(To),
|
||||
NewAttrs),
|
||||
Text = xml:element_to_string({xmlelement, Name, Attrs2, Els}),
|
||||
FixedPacket = {xmlelement, Name, Attrs2, Els},
|
||||
Text = xml:element_to_string(FixedPacket),
|
||||
send_text(StateData, Text),
|
||||
ejabberd_hooks:run(user_receive_packet,
|
||||
[StateData#state.jid, From, To, FixedPacket]),
|
||||
{next_state, StateName, NewState};
|
||||
true ->
|
||||
{next_state, StateName, NewState}
|
||||
|
@ -1102,6 +1110,8 @@ presence_update(From, Packet, StateData) ->
|
|||
NewState =
|
||||
if
|
||||
FromUnavail ->
|
||||
ejabberd_hooks:run(user_available_hook,
|
||||
[StateData#state.jid]),
|
||||
resend_offline_messages(StateData),
|
||||
presence_broadcast_first(
|
||||
From, StateData#state{pres_last = Packet,
|
||||
|
@ -1385,17 +1395,37 @@ process_privacy_iq(From, To,
|
|||
NewStateData.
|
||||
|
||||
|
||||
resend_offline_messages(StateData) ->
|
||||
resend_offline_messages(#state{user = User,
|
||||
privacy_list = PrivList} = StateData) ->
|
||||
case ejabberd_hooks:run_fold(resend_offline_messages_hook, [],
|
||||
[StateData#state.user]) of
|
||||
[User]) of
|
||||
Rs when list(Rs) ->
|
||||
lists:foreach(
|
||||
fun({route, From, To, {xmlelement, Name, Attrs, Els}}) ->
|
||||
Attrs2 = jlib:replace_from_to_attrs(
|
||||
jlib:jid_to_string(From),
|
||||
jlib:jid_to_string(To),
|
||||
Attrs),
|
||||
send_element(StateData, {xmlelement, Name, Attrs2, Els})
|
||||
fun({route,
|
||||
From, To, {xmlelement, Name, Attrs, Els} = Packet}) ->
|
||||
Pass = case catch mod_privacy:check_packet(
|
||||
User,
|
||||
PrivList,
|
||||
{From, To, Packet},
|
||||
in) of
|
||||
{'EXIT', _Reason} ->
|
||||
true;
|
||||
allow ->
|
||||
true;
|
||||
deny ->
|
||||
false
|
||||
end,
|
||||
if
|
||||
Pass ->
|
||||
Attrs2 = jlib:replace_from_to_attrs(
|
||||
jlib:jid_to_string(From),
|
||||
jlib:jid_to_string(To),
|
||||
Attrs),
|
||||
send_element(StateData,
|
||||
{xmlelement, Name, Attrs2, Els});
|
||||
true ->
|
||||
ok
|
||||
end
|
||||
end, Rs)
|
||||
end.
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ run_fold(Hook, Val, Args) ->
|
|||
[{_, Ls}] ->
|
||||
run_fold1(Ls, Hook, Val, Args);
|
||||
[] ->
|
||||
ok
|
||||
Val
|
||||
end.
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
-export([register_iq_handler/3,
|
||||
register_iq_handler/4,
|
||||
unregister_iq_handler/1,
|
||||
refresh_iq_handlers/0
|
||||
refresh_iq_handlers/0,
|
||||
bounce_resource_packet/3
|
||||
]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
|
@ -32,6 +33,8 @@ init() ->
|
|||
MyDomain = ?MYNAME,
|
||||
ejabberd_router:register_route(MyDomain),
|
||||
catch ets:new(local_iqtable, [named_table, public]),
|
||||
ejabberd_hooks:add(local_send_to_resource_hook,
|
||||
?MODULE, bounce_resource_packet, 100),
|
||||
loop(#state{mydomain = MyDomain,
|
||||
iqtable = local_iqtable}).
|
||||
|
||||
|
@ -104,14 +107,8 @@ do_route(State, From, To, Packet) ->
|
|||
"error" -> ok;
|
||||
"result" -> ok;
|
||||
_ ->
|
||||
case {Res, Name} of
|
||||
{"announce/online", "message"} ->
|
||||
announce_online(From, To, Packet);
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERR_ITEM_NOT_FOUND),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end
|
||||
ejabberd_hooks:run(local_send_to_resource_hook,
|
||||
[From, To, Packet])
|
||||
end;
|
||||
_ ->
|
||||
ejabberd_sm ! {route, From, To, Packet}
|
||||
|
@ -159,17 +156,7 @@ unregister_iq_handler(XMLNS) ->
|
|||
refresh_iq_handlers() ->
|
||||
ejabberd_local ! refresh_iq_handlers.
|
||||
|
||||
announce_online(From, To, Packet) ->
|
||||
case acl:match_rule(announce, From) of
|
||||
deny ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
Local = jlib:make_jid("", ?MYNAME, ""),
|
||||
lists:foreach(
|
||||
fun({U, R}) ->
|
||||
Dest = jlib:make_jid(U, ?MYNAME, R),
|
||||
ejabberd_router:route(Local, Dest, Packet)
|
||||
end, ejabberd_sm:dirty_get_sessions_list())
|
||||
end.
|
||||
|
||||
bounce_resource_packet(From, To, Packet) ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_ITEM_NOT_FOUND),
|
||||
ejabberd_router:route(To, From, Err),
|
||||
stop.
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
%%%----------------------------------------------------------------------
|
||||
%%% File : mod_announce.erl
|
||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Purpose : Manage announce messages
|
||||
%%% Created : 11 Aug 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(mod_announce).
|
||||
-author('alexey@sevcom.net').
|
||||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
-export([start/1,
|
||||
init/0,
|
||||
stop/0,
|
||||
announce/3,
|
||||
send_motd/1]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-record(motd, {id, packet}).
|
||||
-record(motd_users, {luser, dummy = []}).
|
||||
|
||||
-define(PROCNAME, ejabberd_announce).
|
||||
|
||||
start(_) ->
|
||||
mnesia:create_table(motd, [{disc_copies, [node()]},
|
||||
{attributes, record_info(fields, motd)}]),
|
||||
mnesia:create_table(motd_users, [{disc_copies, [node()]},
|
||||
{attributes, record_info(fields, motd_users)}]),
|
||||
ejabberd_hooks:add(local_send_to_resource_hook,
|
||||
?MODULE, announce, 50),
|
||||
ejabberd_hooks:add(user_available_hook,
|
||||
?MODULE, send_motd, 50),
|
||||
register(?PROCNAME, proc_lib:spawn(?MODULE, init, [])).
|
||||
|
||||
init() ->
|
||||
loop().
|
||||
|
||||
loop() ->
|
||||
receive
|
||||
{announce_online, From, To, Packet} ->
|
||||
announce_online(From, To, Packet),
|
||||
loop();
|
||||
{announce_motd, From, To, Packet} ->
|
||||
announce_motd(From, To, Packet),
|
||||
loop();
|
||||
{announce_motd_update, From, To, Packet} ->
|
||||
announce_motd_update(From, To, Packet),
|
||||
loop();
|
||||
{announce_motd_delete, From, To, Packet} ->
|
||||
announce_motd_delete(From, To, Packet),
|
||||
loop();
|
||||
_ ->
|
||||
loop()
|
||||
end.
|
||||
|
||||
stop() ->
|
||||
ejabberd_hooks:delete(local_send_to_resource_hook,
|
||||
?MODULE, announce, 50),
|
||||
ejabberd_hooks:delete(sm_register_connection_hook,
|
||||
?MODULE, send_motd, 50),
|
||||
exit(whereis(?PROCNAME), stop),
|
||||
ok.
|
||||
|
||||
announce(From, To, Packet) ->
|
||||
case To of
|
||||
#jid{luser = "", lresource = Res} ->
|
||||
{xmlelement, Name, _Attrs, _Els} = Packet,
|
||||
case {Res, Name} of
|
||||
{"announce/online", "message"} ->
|
||||
?PROCNAME ! {announce_online, From, To, Packet},
|
||||
stop;
|
||||
{"announce/motd", "message"} ->
|
||||
?PROCNAME ! {announce_motd, From, To, Packet},
|
||||
stop;
|
||||
{"announce/motd/update", "message"} ->
|
||||
?PROCNAME ! {announce_motd_update, From, To, Packet},
|
||||
stop;
|
||||
{"announce/motd/delete", "message"} ->
|
||||
?PROCNAME ! {announce_motd_delete, From, To, Packet},
|
||||
stop;
|
||||
_ ->
|
||||
ok
|
||||
end;
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
announce_online(From, To, Packet) ->
|
||||
Access = gen_mod:get_module_opt(?MODULE, access, none),
|
||||
case acl:match_rule(Access, From) of
|
||||
deny ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
announce_online1(ejabberd_sm:dirty_get_sessions_list(), Packet)
|
||||
end.
|
||||
|
||||
announce_online1(Sessions, Packet) ->
|
||||
Server = ?MYNAME,
|
||||
Local = jlib:make_jid("", Server, ""),
|
||||
lists:foreach(
|
||||
fun({U, R}) ->
|
||||
Dest = jlib:make_jid(U, Server, R),
|
||||
ejabberd_router:route(Local, Dest, Packet)
|
||||
end, Sessions).
|
||||
|
||||
announce_motd(From, To, Packet) ->
|
||||
Access = gen_mod:get_module_opt(?MODULE, access, none),
|
||||
case acl:match_rule(Access, From) of
|
||||
deny ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
announce_motd_update(Packet),
|
||||
Sessions = ejabberd_sm:dirty_get_sessions_list(),
|
||||
announce_online1(Sessions, Packet),
|
||||
F = fun() ->
|
||||
lists:foreach(
|
||||
fun({U, _R}) ->
|
||||
mnesia:write(#motd_users{luser = U})
|
||||
end, Sessions)
|
||||
end,
|
||||
mnesia:transaction(F)
|
||||
end.
|
||||
|
||||
announce_motd_update(From, To, Packet) ->
|
||||
Access = gen_mod:get_module_opt(?MODULE, access, none),
|
||||
case acl:match_rule(Access, From) of
|
||||
deny ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
announce_motd_update(Packet)
|
||||
end.
|
||||
|
||||
announce_motd_update(Packet) ->
|
||||
announce_motd_delete(),
|
||||
F = fun() ->
|
||||
mnesia:write(#motd{id = motd, packet = Packet})
|
||||
end,
|
||||
mnesia:transaction(F).
|
||||
|
||||
announce_motd_delete(From, To, Packet) ->
|
||||
Access = gen_mod:get_module_opt(?MODULE, access, none),
|
||||
case acl:match_rule(Access, From) of
|
||||
deny ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
announce_motd_delete()
|
||||
end.
|
||||
|
||||
announce_motd_delete() ->
|
||||
mnesia:clear_table(motd),
|
||||
mnesia:clear_table(motd_users).
|
||||
|
||||
send_motd(#jid{luser = LUser} = JID) ->
|
||||
case catch mnesia:dirty_read({motd, motd}) of
|
||||
[#motd{packet = Packet}] ->
|
||||
case catch mnesia:dirty_read({motd_users, LUser}) of
|
||||
[#motd_users{}] ->
|
||||
ok;
|
||||
_ ->
|
||||
Local = jlib:make_jid("", ?MYNAME, ""),
|
||||
ejabberd_router:route(Local, JID, Packet),
|
||||
F = fun() ->
|
||||
mnesia:write(#motd_users{luser = LUser})
|
||||
end,
|
||||
mnesia:transaction(F)
|
||||
end;
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
Loading…
Reference in New Issue