mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-20 17:27:00 +01:00
* src/mod_vcard_ldap.erl: Bugfix
* src/mod_vcard.erl: Bugfix * src/ejabberd_auth_odbc.erl: Bugfix * doc/dev.tex: Updated SVN Revision: 406
This commit is contained in:
parent
ee3551db4b
commit
a884ba4e8a
14
ChangeLog
14
ChangeLog
@ -1,3 +1,17 @@
|
|||||||
|
2005-08-25 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
|
* src/mod_vcard_ldap.erl: Bugfix
|
||||||
|
|
||||||
|
* src/mod_vcard.erl: Bugfix
|
||||||
|
|
||||||
|
2005-08-23 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
|
* src/ejabberd_auth_odbc.erl: Bugfix
|
||||||
|
|
||||||
|
2005-08-21 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
|
* doc/dev.tex: Updated
|
||||||
|
|
||||||
2005-08-11 Alexey Shchepin <alexey@sevcom.net>
|
2005-08-11 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
* src/cyrsasl_digest.erl: Fixed challenge/response parsing (thanks
|
* src/cyrsasl_digest.erl: Fixed challenge/response parsing (thanks
|
||||||
|
89
doc/dev.html
89
doc/dev.html
@ -4,7 +4,7 @@
|
|||||||
<HEAD><TITLE>Ejabberd Developers Guide</TITLE>
|
<HEAD><TITLE>Ejabberd Developers Guide</TITLE>
|
||||||
|
|
||||||
<META http-equiv="Content-Type" content="text/html; charset=ISO8859-1">
|
<META http-equiv="Content-Type" content="text/html; charset=ISO8859-1">
|
||||||
<META name="GENERATOR" content="hevea 1.06">
|
<META name="GENERATOR" content="hevea 1.07">
|
||||||
</HEAD>
|
</HEAD>
|
||||||
<BODY >
|
<BODY >
|
||||||
<!--HEVEA command line is: /usr/bin/hevea -charset ISO8859-1 dev.tex -->
|
<!--HEVEA command line is: /usr/bin/hevea -charset ISO8859-1 dev.tex -->
|
||||||
@ -21,7 +21,7 @@
|
|||||||
<A HREF="mailto:alexey@sevcom.net"><TT>mailto:alexey@sevcom.net</TT></A><BR>
|
<A HREF="mailto:alexey@sevcom.net"><TT>mailto:alexey@sevcom.net</TT></A><BR>
|
||||||
<A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT></A></H3>
|
<A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT></A></H3>
|
||||||
|
|
||||||
<H3 ALIGN=center>September 10, 2003</H3><DIV ALIGN=center>
|
<H3 ALIGN=center>August 21, 2005</H3><DIV ALIGN=center>
|
||||||
|
|
||||||
<IMG SRC="logo.png">
|
<IMG SRC="logo.png">
|
||||||
|
|
||||||
@ -47,11 +47,12 @@
|
|||||||
</UL>
|
</UL>
|
||||||
<LI><A HREF="#htoc7">2 XML representation</A>
|
<LI><A HREF="#htoc7">2 XML representation</A>
|
||||||
<LI><A HREF="#htoc8">3 Module <TT>xml</TT></A>
|
<LI><A HREF="#htoc8">3 Module <TT>xml</TT></A>
|
||||||
<LI><A HREF="#htoc9">4 <TT>ejabberd</TT> modules</A>
|
<LI><A HREF="#htoc9">4 Module <TT>xml_stream</TT></A>
|
||||||
|
<LI><A HREF="#htoc10">5 <TT>ejabberd</TT> modules</A>
|
||||||
<UL><LI>
|
<UL><LI>
|
||||||
<A HREF="#htoc10">4.1 <CODE>gen_mod</CODE> behaviour</A>
|
<A HREF="#htoc11">5.1 <CODE>gen_mod</CODE> behaviour</A>
|
||||||
<LI><A HREF="#htoc11">4.2 Module <CODE>gen_iq_handler</CODE></A>
|
<LI><A HREF="#htoc12">5.2 Module <CODE>gen_iq_handler</CODE></A>
|
||||||
<LI><A HREF="#htoc12">4.3 Services</A>
|
<LI><A HREF="#htoc13">5.3 Services</A>
|
||||||
</UL>
|
</UL>
|
||||||
</UL>
|
</UL>
|
||||||
|
|
||||||
@ -90,9 +91,6 @@ Works on most of popular platforms: *nix (tested on Linux, FreeBSD and
|
|||||||
<LI>Support for <A HREF="http://www.jabber.org/jeps/jep-0039.html">Statistics Gathering</A>.
|
<LI>Support for <A HREF="http://www.jabber.org/jeps/jep-0039.html">Statistics Gathering</A>.
|
||||||
<LI>Support for <TT>xml:lang</TT>
|
<LI>Support for <TT>xml:lang</TT>
|
||||||
</UL>
|
</UL>
|
||||||
<TT>ejabberd</TT> is a Free and Open Source fault-tolerant distributed Jabber
|
|
||||||
server. It is written mostly in Erlang.<BR>
|
|
||||||
<BR>
|
|
||||||
<!--TOC subsection How it works-->
|
<!--TOC subsection How it works-->
|
||||||
|
|
||||||
<H3><A NAME="htoc2">1.1</A> How it works</H3><!--SEC END -->
|
<H3><A NAME="htoc2">1.1</A> How it works</H3><!--SEC END -->
|
||||||
@ -158,7 +156,7 @@ does not exist, then it is opened and registered.<BR>
|
|||||||
<H2><A NAME="htoc7">2</A> XML representation</H2><!--SEC END -->
|
<H2><A NAME="htoc7">2</A> XML representation</H2><!--SEC END -->
|
||||||
|
|
||||||
<A NAME="sec:xmlrepr"></A>
|
<A NAME="sec:xmlrepr"></A>
|
||||||
Each XML stanza represented as following tuple:
|
Each XML stanza is represented as the following tuple:
|
||||||
<PRE>
|
<PRE>
|
||||||
XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
|
XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
|
||||||
Name = string()
|
Name = string()
|
||||||
@ -173,7 +171,7 @@ XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
|
|||||||
<message to='test@conference.example.org' type='groupchat'>
|
<message to='test@conference.example.org' type='groupchat'>
|
||||||
<body>test</body>
|
<body>test</body>
|
||||||
</message>
|
</message>
|
||||||
</PRE>represented as following structure:
|
</PRE>is represented as the following structure:
|
||||||
<PRE>
|
<PRE>
|
||||||
{xmlelement, "message",
|
{xmlelement, "message",
|
||||||
[{"to", "test@conference.example.org"},
|
[{"to", "test@conference.example.org"},
|
||||||
@ -233,21 +231,34 @@ Res = string() | XMLElement
|
|||||||
get_tag_attr/2, get_tag_attr_s/2
|
get_tag_attr/2, get_tag_attr_s/2
|
||||||
get_subtag/2
|
get_subtag/2
|
||||||
</PRE></DL>
|
</PRE></DL>
|
||||||
|
<!--TOC section Module <TT>xml_stream</TT>-->
|
||||||
|
|
||||||
|
<H2><A NAME="htoc9">4</A> Module <TT>xml_stream</TT></H2><!--SEC END -->
|
||||||
|
|
||||||
|
<A NAME="sec:xmlstreammod"></A>
|
||||||
|
<DL COMPACT=compact><DT>
|
||||||
|
<CODE><B>parse_element(Str) -> XMLElement | {error, Err}</B></CODE><DD>
|
||||||
|
<PRE>
|
||||||
|
Str = string()
|
||||||
|
Err = term()
|
||||||
|
</PRE>Parses <TT>Str</TT> using XML parser, returns either parsed element or error
|
||||||
|
tuple.
|
||||||
|
</DL>
|
||||||
<!--TOC section <TT>ejabberd</TT> modules-->
|
<!--TOC section <TT>ejabberd</TT> modules-->
|
||||||
|
|
||||||
<H2><A NAME="htoc9">4</A> <TT>ejabberd</TT> modules</H2><!--SEC END -->
|
<H2><A NAME="htoc10">5</A> <TT>ejabberd</TT> modules</H2><!--SEC END -->
|
||||||
|
|
||||||
<A NAME="sec:emods"></A>
|
<A NAME="sec:emods"></A>
|
||||||
<!--TOC subsection <CODE>gen_mod</CODE> behaviour-->
|
<!--TOC subsection <CODE>gen_mod</CODE> behaviour-->
|
||||||
|
|
||||||
<H3><A NAME="htoc10">4.1</A> <CODE>gen_mod</CODE> behaviour</H3><!--SEC END -->
|
<H3><A NAME="htoc11">5.1</A> <CODE>gen_mod</CODE> behaviour</H3><!--SEC END -->
|
||||||
|
|
||||||
<A NAME="sec:genmod"></A>
|
<A NAME="sec:genmod"></A>
|
||||||
TBD<BR>
|
TBD<BR>
|
||||||
<BR>
|
<BR>
|
||||||
<!--TOC subsection Module <CODE>gen_iq_handler</CODE>-->
|
<!--TOC subsection Module <CODE>gen_iq_handler</CODE>-->
|
||||||
|
|
||||||
<H3><A NAME="htoc11">4.2</A> Module <CODE>gen_iq_handler</CODE></H3><!--SEC END -->
|
<H3><A NAME="htoc12">5.2</A> Module <CODE>gen_iq_handler</CODE></H3><!--SEC END -->
|
||||||
|
|
||||||
<A NAME="sec:geniqhandl"></A>
|
<A NAME="sec:geniqhandl"></A>
|
||||||
The module <CODE>gen_iq_handler</CODE> allows to easily write handlers for IQ packets
|
The module <CODE>gen_iq_handler</CODE> allows to easily write handlers for IQ packets
|
||||||
@ -255,23 +266,25 @@ of particular XML namespaces that addressed to server or to users bare JIDs.<BR>
|
|||||||
<BR>
|
<BR>
|
||||||
In this module the following functions are defined:
|
In this module the following functions are defined:
|
||||||
<DL COMPACT=compact><DT>
|
<DL COMPACT=compact><DT>
|
||||||
<CODE><B>add_iq_handler(Component, NS, Module, Function, Type)</B></CODE><DD>
|
<CODE><B>add_iq_handler(Component, Host, NS, Module, Function, Type)</B></CODE><DD>
|
||||||
<PRE>
|
<PRE>
|
||||||
Component = Module = Function = atom()
|
Component = Module = Function = atom()
|
||||||
NS = string()
|
Host = NS = string()
|
||||||
Type = no_queue | one_queue | parallel
|
Type = no_queue | one_queue | parallel
|
||||||
</PRE>Registers function <CODE>Module:Function</CODE> as handler for IQ packets that
|
</PRE>Registers function <CODE>Module:Function</CODE> as handler for IQ packets on
|
||||||
contain child of namespace <CODE>NS</CODE> in <CODE>Component</CODE>. Queueing
|
virtual host <CODE>Host</CODE> that contain child of namespace <CODE>NS</CODE> in
|
||||||
discipline is <CODE>Type</CODE>. There are at least two components defined:
|
<CODE>Component</CODE>. Queueing discipline is <CODE>Type</CODE>. There are at least
|
||||||
|
two components defined:
|
||||||
<DL COMPACT=compact><DT>
|
<DL COMPACT=compact><DT>
|
||||||
<CODE><B>ejabberd_local</B></CODE><DD> Handles packets that addressed to server JID;
|
<CODE><B>ejabberd_local</B></CODE><DD> Handles packets that addressed to server JID;
|
||||||
<DT><CODE><B>ejabberd_sm</B></CODE><DD> Handles packets that addressed to users bare JIDs.
|
<DT><CODE><B>ejabberd_sm</B></CODE><DD> Handles packets that addressed to users bare JIDs.
|
||||||
</DL>
|
</DL>
|
||||||
<DT><CODE><B>remove_iq_handler(Component, NS)</B></CODE><DD>
|
<DT><CODE><B>remove_iq_handler(Component, Host, NS)</B></CODE><DD>
|
||||||
<PRE>
|
<PRE>
|
||||||
Component = atom()
|
Component = atom()
|
||||||
NS = string()
|
Host = NS = string()
|
||||||
</PRE>Removes IQ handler for namespace <CODE>NS</CODE> from <CODE>Component</CODE>.
|
</PRE>Removes IQ handler on virtual host <CODE>Host</CODE> for namespace <CODE>NS</CODE> from
|
||||||
|
<CODE>Component</CODE>.
|
||||||
</DL>
|
</DL>
|
||||||
Handler function must have the following type:
|
Handler function must have the following type:
|
||||||
<DL COMPACT=compact><DT>
|
<DL COMPACT=compact><DT>
|
||||||
@ -284,8 +297,8 @@ From = To = jid()
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1,
|
-export([start/2,
|
||||||
stop/0,
|
stop/1,
|
||||||
process_local_iq/3]).
|
process_local_iq/3]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
@ -293,13 +306,13 @@ From = To = jid()
|
|||||||
|
|
||||||
-define(NS_CPUTIME, "ejabberd:cputime").
|
-define(NS_CPUTIME, "ejabberd:cputime").
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_CPUTIME,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_CPUTIME,
|
||||||
?MODULE, process_local_iq, IQDisc).
|
?MODULE, process_local_iq, IQDisc).
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_CPUTIME).
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_CPUTIME).
|
||||||
|
|
||||||
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||||
case Type of
|
case Type of
|
||||||
@ -317,7 +330,7 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
|||||||
</PRE>
|
</PRE>
|
||||||
<!--TOC subsection Services-->
|
<!--TOC subsection Services-->
|
||||||
|
|
||||||
<H3><A NAME="htoc12">4.3</A> Services</H3><!--SEC END -->
|
<H3><A NAME="htoc13">5.3</A> Services</H3><!--SEC END -->
|
||||||
|
|
||||||
<A NAME="sec:services"></A>
|
<A NAME="sec:services"></A>
|
||||||
TBD<BR>
|
TBD<BR>
|
||||||
@ -328,14 +341,15 @@ TODO: use <CODE>proc_lib</CODE>
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1, init/1, stop/0]).
|
-export([start/2, init/1, stop/1]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
Host = gen_mod:get_opt(host, Opts, "echo." ++ ?MYNAME),
|
MyHost = gen_mod:get_opt(host, Opts, "echo." ++ Host),
|
||||||
register(ejabberd_mod_echo, spawn(?MODULE, init, [Host])).
|
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
|
spawn(?MODULE, init, [MyHost])).
|
||||||
|
|
||||||
init(Host) ->
|
init(Host) ->
|
||||||
ejabberd_router:register_local_route(Host),
|
ejabberd_router:register_local_route(Host),
|
||||||
@ -347,15 +361,16 @@ loop(Host) ->
|
|||||||
ejabberd_router:route(To, From, Packet),
|
ejabberd_router:route(To, From, Packet),
|
||||||
loop(Host);
|
loop(Host);
|
||||||
stop ->
|
stop ->
|
||||||
ejabberd_router:unregister_local_route(Host),
|
ejabberd_router:unregister_route(Host),
|
||||||
ok;
|
ok;
|
||||||
_ ->
|
_ ->
|
||||||
loop(Host)
|
loop(Host)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
ejabberd_mod_echo ! stop,
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
ok.
|
Proc ! stop,
|
||||||
|
{wait, Proc}.
|
||||||
</PRE>
|
</PRE>
|
||||||
<!--HTMLFOOT-->
|
<!--HTMLFOOT-->
|
||||||
<!--ENDHTML-->
|
<!--ENDHTML-->
|
||||||
|
68
doc/dev.tex
68
doc/dev.tex
@ -41,7 +41,7 @@
|
|||||||
\author{Alexey Shchepin \\
|
\author{Alexey Shchepin \\
|
||||||
\ahrefurl{mailto:alexey@sevcom.net} \\
|
\ahrefurl{mailto:alexey@sevcom.net} \\
|
||||||
\ahrefurl{xmpp:aleksey@jabber.ru}}
|
\ahrefurl{xmpp:aleksey@jabber.ru}}
|
||||||
\date{September 10, 2003}
|
\date{August 21, 2005}
|
||||||
|
|
||||||
\begin{document}
|
\begin{document}
|
||||||
\begin{titlepage}
|
\begin{titlepage}
|
||||||
@ -89,8 +89,6 @@ The main features of \ejabberd{} are:
|
|||||||
\item Support for \tjepref{0039}{Statistics Gathering}.
|
\item Support for \tjepref{0039}{Statistics Gathering}.
|
||||||
\item Support for \ns{xml:lang}
|
\item Support for \ns{xml:lang}
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\ejabberd{} is a Free and Open Source fault-tolerant distributed \Jabber{}
|
|
||||||
server. It is written mostly in Erlang.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -158,7 +156,7 @@ does not exist, then it is opened and registered.
|
|||||||
\section{XML representation}
|
\section{XML representation}
|
||||||
\label{sec:xmlrepr}
|
\label{sec:xmlrepr}
|
||||||
|
|
||||||
Each XML stanza represented as following tuple:
|
Each XML stanza is represented as the following tuple:
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
|
XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
|
||||||
Name = string()
|
Name = string()
|
||||||
@ -175,7 +173,7 @@ E.\,g. this stanza:
|
|||||||
<body>test</body>
|
<body>test</body>
|
||||||
</message>
|
</message>
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
represented as following structure:
|
is represented as the following structure:
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
{xmlelement, "message",
|
{xmlelement, "message",
|
||||||
[{"to", "test@conference.example.org"},
|
[{"to", "test@conference.example.org"},
|
||||||
@ -245,6 +243,18 @@ Res = string() | XMLElement
|
|||||||
\end{description}
|
\end{description}
|
||||||
|
|
||||||
|
|
||||||
|
\section{Module \texttt{xml\_stream}}
|
||||||
|
\label{sec:xmlstreammod}
|
||||||
|
|
||||||
|
\begin{description}
|
||||||
|
\item[\verb!parse_element(Str) -> XMLElement | {error, Err}!]
|
||||||
|
\begin{verbatim}
|
||||||
|
Str = string()
|
||||||
|
Err = term()
|
||||||
|
\end{verbatim}
|
||||||
|
Parses \texttt{Str} using XML parser, returns either parsed element or error
|
||||||
|
tuple.
|
||||||
|
\end{description}
|
||||||
|
|
||||||
|
|
||||||
\section{\ejabberd{} modules}
|
\section{\ejabberd{} modules}
|
||||||
@ -264,25 +274,27 @@ of particular XML namespaces that addressed to server or to users bare JIDs.
|
|||||||
|
|
||||||
In this module the following functions are defined:
|
In this module the following functions are defined:
|
||||||
\begin{description}
|
\begin{description}
|
||||||
\item[\verb|add_iq_handler(Component, NS, Module, Function, Type)|]
|
\item[\verb|add_iq_handler(Component, Host, NS, Module, Function, Type)|]
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
Component = Module = Function = atom()
|
Component = Module = Function = atom()
|
||||||
NS = string()
|
Host = NS = string()
|
||||||
Type = no_queue | one_queue | parallel
|
Type = no_queue | one_queue | parallel
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
Registers function \verb|Module:Function| as handler for IQ packets that
|
Registers function \verb|Module:Function| as handler for IQ packets on
|
||||||
contain child of namespace \verb|NS| in \verb|Component|. Queueing
|
virtual host \verb|Host| that contain child of namespace \verb|NS| in
|
||||||
discipline is \verb|Type|. There are at least two components defined:
|
\verb|Component|. Queueing discipline is \verb|Type|. There are at least
|
||||||
|
two components defined:
|
||||||
\begin{description}
|
\begin{description}
|
||||||
\item[\verb|ejabberd_local|] Handles packets that addressed to server JID;
|
\item[\verb|ejabberd_local|] Handles packets that addressed to server JID;
|
||||||
\item[\verb|ejabberd_sm|] Handles packets that addressed to users bare JIDs.
|
\item[\verb|ejabberd_sm|] Handles packets that addressed to users bare JIDs.
|
||||||
\end{description}
|
\end{description}
|
||||||
\item[\verb|remove_iq_handler(Component, NS)|]
|
\item[\verb|remove_iq_handler(Component, Host, NS)|]
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
Component = atom()
|
Component = atom()
|
||||||
NS = string()
|
Host = NS = string()
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
Removes IQ handler for namespace \verb|NS| from \verb|Component|.
|
Removes IQ handler on virtual host \verb|Host| for namespace \verb|NS| from
|
||||||
|
\verb|Component|.
|
||||||
\end{description}
|
\end{description}
|
||||||
|
|
||||||
Handler function must have the following type:
|
Handler function must have the following type:
|
||||||
@ -300,8 +312,8 @@ From = To = jid()
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1,
|
-export([start/2,
|
||||||
stop/0,
|
stop/1,
|
||||||
process_local_iq/3]).
|
process_local_iq/3]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
@ -309,13 +321,13 @@ From = To = jid()
|
|||||||
|
|
||||||
-define(NS_CPUTIME, "ejabberd:cputime").
|
-define(NS_CPUTIME, "ejabberd:cputime").
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_CPUTIME,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_CPUTIME,
|
||||||
?MODULE, process_local_iq, IQDisc).
|
?MODULE, process_local_iq, IQDisc).
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_CPUTIME).
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_CPUTIME).
|
||||||
|
|
||||||
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||||
case Type of
|
case Type of
|
||||||
@ -345,14 +357,15 @@ TODO: use \verb|proc_lib|
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1, init/1, stop/0]).
|
-export([start/2, init/1, stop/1]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
Host = gen_mod:get_opt(host, Opts, "echo." ++ ?MYNAME),
|
MyHost = gen_mod:get_opt(host, Opts, "echo." ++ Host),
|
||||||
register(ejabberd_mod_echo, spawn(?MODULE, init, [Host])).
|
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
|
spawn(?MODULE, init, [MyHost])).
|
||||||
|
|
||||||
init(Host) ->
|
init(Host) ->
|
||||||
ejabberd_router:register_local_route(Host),
|
ejabberd_router:register_local_route(Host),
|
||||||
@ -364,15 +377,16 @@ loop(Host) ->
|
|||||||
ejabberd_router:route(To, From, Packet),
|
ejabberd_router:route(To, From, Packet),
|
||||||
loop(Host);
|
loop(Host);
|
||||||
stop ->
|
stop ->
|
||||||
ejabberd_router:unregister_local_route(Host),
|
ejabberd_router:unregister_route(Host),
|
||||||
ok;
|
ok;
|
||||||
_ ->
|
_ ->
|
||||||
loop(Host)
|
loop(Host)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
ejabberd_mod_echo ! stop,
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
ok.
|
Proc ! stop,
|
||||||
|
{wait, Proc}.
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
|
|
||||||
|
@ -122,11 +122,12 @@ dirty_get_registered_users() ->
|
|||||||
get_vh_registered_users(?MYNAME).
|
get_vh_registered_users(?MYNAME).
|
||||||
|
|
||||||
get_vh_registered_users(Server) ->
|
get_vh_registered_users(Server) ->
|
||||||
|
LServer = jlib:nameprep(Server),
|
||||||
case catch ejabberd_odbc:sql_query(
|
case catch ejabberd_odbc:sql_query(
|
||||||
jlib:nameprep(Server),
|
LServer,
|
||||||
"select username from users") of
|
"select username from users") of
|
||||||
{selected, ["username"], Res} ->
|
{selected, ["username"], Res} ->
|
||||||
[U || {U} <- Res];
|
[{U, LServer} || {U} <- Res];
|
||||||
_ ->
|
_ ->
|
||||||
[]
|
[]
|
||||||
end.
|
end.
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, init/2, stop/1,
|
-export([start/2, init/3, stop/1,
|
||||||
process_local_iq/3,
|
process_local_iq/3,
|
||||||
process_sm_iq/3,
|
process_sm_iq/3,
|
||||||
reindex_vcards/0,
|
reindex_vcards/0,
|
||||||
@ -70,36 +70,36 @@ start(Host, Opts) ->
|
|||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
|
||||||
?MODULE, process_sm_iq, IQDisc),
|
?MODULE, process_sm_iq, IQDisc),
|
||||||
catch mod_disco:register_sm_feature(Host, ?NS_VCARD),
|
catch mod_disco:register_sm_feature(Host, ?NS_VCARD),
|
||||||
Hosts = gen_mod:get_hosts(Opts, "vjud."),
|
MyHost = gen_mod:get_opt(host, Opts, "vjud." ++ Host),
|
||||||
Search = gen_mod:get_opt(search, Opts, true),
|
Search = gen_mod:get_opt(search, Opts, true),
|
||||||
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
spawn(?MODULE, init, [Hosts, Search])).
|
spawn(?MODULE, init, [MyHost, Host, Search])).
|
||||||
|
|
||||||
|
|
||||||
init(Hosts, Search) ->
|
init(Host, ServerHost, Search) ->
|
||||||
case Search of
|
case Search of
|
||||||
false ->
|
false ->
|
||||||
loop(Hosts);
|
loop(Host, ServerHost);
|
||||||
_ ->
|
_ ->
|
||||||
ejabberd_router:register_routes(Hosts),
|
ejabberd_router:register_route(Host),
|
||||||
loop(Hosts)
|
loop(Host, ServerHost)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
loop(Hosts) ->
|
loop(Host, ServerHost) ->
|
||||||
receive
|
receive
|
||||||
{route, From, To, Packet} ->
|
{route, From, To, Packet} ->
|
||||||
case catch do_route(From, To, Packet) of
|
case catch do_route(ServerHost, From, To, Packet) of
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
?ERROR_MSG("~p", [Reason]);
|
?ERROR_MSG("~p", [Reason]);
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
loop(Hosts);
|
loop(Host, ServerHost);
|
||||||
stop ->
|
stop ->
|
||||||
catch ejabberd_router:unregister_routes(Hosts),
|
ejabberd_router:unregister_route(Host),
|
||||||
ok;
|
ok;
|
||||||
_ ->
|
_ ->
|
||||||
loop(Hosts)
|
loop(Host, ServerHost)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
stop(Host) ->
|
stop(Host) ->
|
||||||
@ -272,7 +272,7 @@ set_vcard(User, LServer, VCARD) ->
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
do_route(From, To, Packet) ->
|
do_route(ServerHost, From, To, Packet) ->
|
||||||
#jid{user = User, resource = Resource} = To,
|
#jid{user = User, resource = Resource} = To,
|
||||||
if
|
if
|
||||||
(User /= "") or (Resource /= "") ->
|
(User /= "") or (Resource /= "") ->
|
||||||
@ -310,7 +310,7 @@ do_route(From, To, Packet) ->
|
|||||||
[{xmlelement, "x",
|
[{xmlelement, "x",
|
||||||
[{"xmlns", ?NS_XDATA},
|
[{"xmlns", ?NS_XDATA},
|
||||||
{"type", "result"}],
|
{"type", "result"}],
|
||||||
search_result(Lang, To, XData)
|
search_result(Lang, To, ServerHost, XData)
|
||||||
}]}]},
|
}]}]},
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
To, From, jlib:iq_to_xml(ResIQ))
|
To, From, jlib:iq_to_xml(ResIQ))
|
||||||
@ -420,7 +420,7 @@ find_xdata_el1([_ | Els]) ->
|
|||||||
{xmlelement, "field", [{"label", translate:translate(Lang, Label)},
|
{xmlelement, "field", [{"label", translate:translate(Lang, Label)},
|
||||||
{"var", Var}], []}).
|
{"var", Var}], []}).
|
||||||
|
|
||||||
search_result(Lang, JID, Data) ->
|
search_result(Lang, JID, ServerHost, Data) ->
|
||||||
[{xmlelement, "title", [],
|
[{xmlelement, "title", [],
|
||||||
[{xmlcdata, translate:translate(Lang, "Results of search in ") ++
|
[{xmlcdata, translate:translate(Lang, "Results of search in ") ++
|
||||||
jlib:jid_to_string(JID)}]},
|
jlib:jid_to_string(JID)}]},
|
||||||
@ -437,7 +437,7 @@ search_result(Lang, JID, Data) ->
|
|||||||
?LFIELD("email", "email"),
|
?LFIELD("email", "email"),
|
||||||
?LFIELD("Organization Name", "orgname"),
|
?LFIELD("Organization Name", "orgname"),
|
||||||
?LFIELD("Organization Unit", "orgunit")
|
?LFIELD("Organization Unit", "orgunit")
|
||||||
]}] ++ lists:map(fun record_to_item/1, search(JID#jid.lserver, Data)).
|
]}] ++ lists:map(fun record_to_item/1, search(ServerHost, Data)).
|
||||||
|
|
||||||
-define(FIELD(Var, Val),
|
-define(FIELD(Var, Val),
|
||||||
{xmlelement, "field", [{"var", Var}],
|
{xmlelement, "field", [{"var", Var}],
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, init/2, stop/1,
|
-export([start/2, init/3, stop/1,
|
||||||
process_local_iq/3,
|
process_local_iq/3,
|
||||||
process_sm_iq/3,
|
process_sm_iq/3,
|
||||||
remove_user/1]).
|
remove_user/1]).
|
||||||
@ -21,6 +21,7 @@
|
|||||||
-include("eldap/eldap.hrl").
|
-include("eldap/eldap.hrl").
|
||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
|
|
||||||
|
-define(PROCNAME, ejabberd_mod_vcard_ldap).
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
@ -28,45 +29,47 @@ start(Host, Opts) ->
|
|||||||
?MODULE, process_local_iq, IQDisc),
|
?MODULE, process_local_iq, IQDisc),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
|
||||||
?MODULE, process_sm_iq, IQDisc),
|
?MODULE, process_sm_iq, IQDisc),
|
||||||
LDAPServers = ejabberd_config:get_local_option(ldap_servers),
|
LDAPServers = ejabberd_config:get_local_option({ldap_servers, Host}),
|
||||||
RootDN = ejabberd_config:get_local_option(ldap_rootdn),
|
RootDN = ejabberd_config:get_local_option({ldap_rootdn, Host}),
|
||||||
Password = ejabberd_config:get_local_option(ldap_password),
|
Password = ejabberd_config:get_local_option({ldap_password, Host}),
|
||||||
eldap:start_link("mod_vcard_ldap", LDAPServers, 389, RootDN, Password),
|
eldap:start_link("mod_vcard_ldap", LDAPServers, 389, RootDN, Password),
|
||||||
Host = gen_mod:get_opt(host, Opts, "vjud." ++ ?MYNAME),
|
MyHost = gen_mod:get_opt(host, Opts, "vjud." ++ Host),
|
||||||
Search = gen_mod:get_opt(search, Opts, true),
|
Search = gen_mod:get_opt(search, Opts, true),
|
||||||
register(ejabberd_mod_vcard_ldap, spawn(?MODULE, init, [Host, Search])).
|
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
|
spawn(?MODULE, init, [MyHost, Host, Search])).
|
||||||
|
|
||||||
init(Host, Search) ->
|
init(Host, ServerHost, Search) ->
|
||||||
case Search of
|
case Search of
|
||||||
false ->
|
false ->
|
||||||
loop(Host);
|
loop(Host, ServerHost);
|
||||||
_ ->
|
_ ->
|
||||||
ejabberd_router:register_route(Host),
|
ejabberd_router:register_route(Host),
|
||||||
loop(Host)
|
loop(Host, ServerHost)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
loop(Host) ->
|
loop(Host, ServerHost) ->
|
||||||
receive
|
receive
|
||||||
{route, From, To, Packet} ->
|
{route, From, To, Packet} ->
|
||||||
case catch do_route(From, To, Packet) of
|
case catch do_route(ServerHost, From, To, Packet) of
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
?ERROR_MSG("~p", [Reason]);
|
?ERROR_MSG("~p", [Reason]);
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
loop(Host);
|
loop(Host, ServerHost);
|
||||||
stop ->
|
stop ->
|
||||||
catch ejabberd_router:unregister_route(Host),
|
ejabberd_router:unregister_route(Host),
|
||||||
ok;
|
ok;
|
||||||
_ ->
|
_ ->
|
||||||
loop(Host)
|
loop(Host, ServerHost)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
stop(Host) ->
|
stop(Host) ->
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD),
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD),
|
||||||
ejabberd_mod_vcard_ldap ! stop,
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
ok.
|
Proc ! stop,
|
||||||
|
{wait, Proc}.
|
||||||
|
|
||||||
process_local_iq(_From, _To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
process_local_iq(_From, _To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
||||||
case Type of
|
case Type of
|
||||||
@ -92,10 +95,10 @@ process_local_iq(_From, _To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ)
|
|||||||
]}]}
|
]}]}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
find_ldap_user(User) ->
|
find_ldap_user(Host, User) ->
|
||||||
Attr = ejabberd_config:get_local_option(ldap_uidattr),
|
Attr = ejabberd_config:get_local_option({ldap_uidattr, Host}),
|
||||||
Filter = eldap:equalityMatch(Attr, User),
|
Filter = eldap:equalityMatch(Attr, User),
|
||||||
Base = ejabberd_config:get_local_option(ldap_base),
|
Base = ejabberd_config:get_local_option({ldap_base, Host}),
|
||||||
case eldap:search("mod_vcard_ldap", [{base, Base},
|
case eldap:search("mod_vcard_ldap", [{base, Base},
|
||||||
{filter, Filter},
|
{filter, Filter},
|
||||||
{attributes, []}]) of
|
{attributes, []}]) of
|
||||||
@ -192,12 +195,13 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
|||||||
set ->
|
set ->
|
||||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||||
get ->
|
get ->
|
||||||
#jid{luser = LUser} = To,
|
#jid{luser = LUser, lserver = LServer} = To,
|
||||||
case find_ldap_user(LUser) of
|
case find_ldap_user(LServer, LUser) of
|
||||||
#eldap_entry{attributes = Attributes} ->
|
#eldap_entry{attributes = Attributes} ->
|
||||||
Vcard = ldap_attributes_to_vcard(Attributes,From,To),
|
Vcard = ldap_attributes_to_vcard(Attributes,From,To),
|
||||||
IQ#iq{type = result, sub_el = Vcard};
|
IQ#iq{type = result, sub_el = Vcard};
|
||||||
_ -> IQ#iq{type = result, sub_el = []}
|
_ ->
|
||||||
|
IQ#iq{type = result, sub_el = []}
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@ -234,7 +238,7 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
do_route(From, To, Packet) ->
|
do_route(ServerHost, From, To, Packet) ->
|
||||||
#jid{user = User, resource = Resource} = To,
|
#jid{user = User, resource = Resource} = To,
|
||||||
if
|
if
|
||||||
(User /= "") or (Resource /= "") ->
|
(User /= "") or (Resource /= "") ->
|
||||||
@ -272,7 +276,7 @@ do_route(From, To, Packet) ->
|
|||||||
[{xmlelement, "x",
|
[{xmlelement, "x",
|
||||||
[{"xmlns", ?NS_XDATA},
|
[{"xmlns", ?NS_XDATA},
|
||||||
{"type", "result"}],
|
{"type", "result"}],
|
||||||
search_result(Lang, To, XData)
|
search_result(Lang, To, ServerHost, XData)
|
||||||
}]}]},
|
}]}]},
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
To, From, jlib:iq_to_xml(ResIQ))
|
To, From, jlib:iq_to_xml(ResIQ))
|
||||||
@ -382,7 +386,7 @@ find_xdata_el1([_ | Els]) ->
|
|||||||
{xmlelement, "field", [{"label", translate:translate(Lang, Label)},
|
{xmlelement, "field", [{"label", translate:translate(Lang, Label)},
|
||||||
{"var", Var}], []}).
|
{"var", Var}], []}).
|
||||||
|
|
||||||
search_result(Lang, JID, Data) ->
|
search_result(Lang, JID, ServerHost, Data) ->
|
||||||
[{xmlelement, "title", [],
|
[{xmlelement, "title", [],
|
||||||
[{xmlcdata, translate:translate(Lang, "Results of search in ") ++
|
[{xmlcdata, translate:translate(Lang, "Results of search in ") ++
|
||||||
jlib:jid_to_string(JID)}]},
|
jlib:jid_to_string(JID)}]},
|
||||||
@ -401,7 +405,7 @@ search_result(Lang, JID, Data) ->
|
|||||||
?LFIELD("Organization Unit", "orgunit")
|
?LFIELD("Organization Unit", "orgunit")
|
||||||
]}] ++ lists:map(fun(E) ->
|
]}] ++ lists:map(fun(E) ->
|
||||||
record_to_item(E#eldap_entry.attributes)
|
record_to_item(E#eldap_entry.attributes)
|
||||||
end, search(JID#jid.lserver, Data)).
|
end, search(ServerHost, Data)).
|
||||||
|
|
||||||
-define(FIELD(Var, Val),
|
-define(FIELD(Var, Val),
|
||||||
{xmlelement, "field", [{"var", Var}],
|
{xmlelement, "field", [{"var", Var}],
|
||||||
@ -491,8 +495,8 @@ record_to_item(Attributes) ->
|
|||||||
|
|
||||||
search(LServer, Data) ->
|
search(LServer, Data) ->
|
||||||
Filter = make_filter(Data),
|
Filter = make_filter(Data),
|
||||||
Base = ejabberd_config:get_local_option(ldap_base),
|
Base = ejabberd_config:get_local_option({ldap_base, LServer}),
|
||||||
UIDAttr = ejabberd_config:get_local_option(ldap_uidattr),
|
UIDAttr = ejabberd_config:get_local_option({ldap_uidattr, LServer}),
|
||||||
case eldap:search("mod_vcard_ldap",[{base, Base},
|
case eldap:search("mod_vcard_ldap",[{base, Base},
|
||||||
{filter, Filter},
|
{filter, Filter},
|
||||||
{attributes, []}]) of
|
{attributes, []}]) of
|
||||||
@ -500,8 +504,10 @@ search(LServer, Data) ->
|
|||||||
[X || X <- E,
|
[X || X <- E,
|
||||||
ejabberd_auth:is_user_exists(
|
ejabberd_auth:is_user_exists(
|
||||||
ldap_get_value(X, UIDAttr), LServer)];
|
ldap_get_value(X, UIDAttr), LServer)];
|
||||||
_ ->
|
Err ->
|
||||||
?ERROR_MSG("~p", ["Bad search"])
|
?ERROR_MSG("Bad search: ~p", [[LServer, {base, Base},
|
||||||
|
{filter, Filter},
|
||||||
|
{attributes, []}]])
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user