diff options
-rw-r--r-- | ChangeLog | 18 | ||||
-rw-r--r-- | doc/guide.html | 65 | ||||
-rw-r--r-- | doc/guide.tex | 65 | ||||
-rw-r--r-- | src/ejabberd_c2s.erl | 26 | ||||
-rw-r--r-- | src/ejabberd_listener.erl | 16 | ||||
-rw-r--r-- | src/jd2ejd.erl | 42 | ||||
-rw-r--r-- | src/mod_configure.erl | 28 | ||||
-rw-r--r-- | src/mod_disco.erl | 24 | ||||
-rw-r--r-- | src/mod_private.erl | 20 | ||||
-rw-r--r-- | src/stringprep/stringprep_drv.c | 53 | ||||
-rw-r--r-- | src/stringprep/uni_norm.c | 21 | ||||
-rw-r--r-- | src/stringprep/uni_parse2.tcl | 21 |
12 files changed, 263 insertions, 136 deletions
@@ -1,3 +1,21 @@ +2003-10-09 Alexey Shchepin <alexey@sevcom.net> + + * src/ejabberd_c2s.erl: Added authentification logging + + * src/ejabberd_listener.erl: Added logging of accepted connections + + * src/stringprep/stringprep_drv.c: Cleanup + + * src/jd2ejd.erl: Added support for iq:private importing + + * src/mod_configure.erl: Fixed user removal + + * src/mod_private.erl: Added remove_user/1 + + * doc/guide.tex: Updated + + * src/mod_disco.erl: Added "extra_domains" option + 2003-10-08 Alexey Shchepin <alexey@sevcom.net> * src/ejabberd_c2s.erl: Added support for "jid-malformed" error diff --git a/doc/guide.html b/doc/guide.html index 241412549..b67031a26 100644 --- a/doc/guide.html +++ b/doc/guide.html @@ -65,7 +65,7 @@ <UL><LI> <A HREF="#htoc19">3.2.1 Node <TT>config</TT>: Global Configuration</A> <LI><A HREF="#htoc20">3.2.2 Node <TT>online users</TT>: List of Online Users</A> -<LI><A HREF="#htoc21">3.2.3 Node <TT>all users</TT>: List of Registered User</A> +<LI><A HREF="#htoc21">3.2.3 Node <TT>all users</TT>: List of Registered Users</A> <LI><A HREF="#htoc22">3.2.4 Node <TT>outgoing s2s</TT>: List of Outgoing S2S connections</A> <LI><A HREF="#htoc23">3.2.5 Node <TT>running nodes</TT>: List of Running <TT>ejabberd</TT> Nodes</A> <LI><A HREF="#htoc24">3.2.6 Node <TT>stopped nodes</TT>: List of Stopped Nodes</A> @@ -411,15 +411,13 @@ runned on them. Each element of list is a tuple with following elements: <UL><LI> Port number; <LI>Module that serves this port; -<LI>Function in this module that starts connection (likely will be removed in - future versions of <TT>ejabberd</TT>); <LI>Options to this module. </UL> Currently three modules are implemented: <DL COMPACT=compact><DT> <B><TT>ejabberd_c2s</TT></B><DD> This module serves C2S connections.<BR> <BR> -Following options defined: +The following options are defined: <DL COMPACT=compact><DT> <B><TT>{access, <access rule>}</TT></B><DD> This option defines access of users to this C2S port. Default value is ``<TT>all</TT>''. @@ -432,10 +430,10 @@ Following options defined: services (i. e. that use the <TT>jabber:component:accept</TT> namespace). </DL> For example, the following configuration defines that C2S connections are -listened on port 5222 and denied for user ``<TT>bad</TT>'', S2S on port 5269 -and that service <TT>conference.jabber.org</TT> must be connected to port 8888 -with a password ``<TT>secret</TT>''. Also all users except admins have traffic -limit 1000 b/s. +listened on port 5222 and 5223 (SSL) and denied for user ``<TT>bad</TT>'', S2S +on port 5269, and that service <TT>conference.example.org</TT> must be +connected to port 8888 with a password ``<TT>secret</TT>''. Also all users +except admins have traffic limit 1000 b/s. <PRE> {acl, blocked, {user, "bad"}}. {access, c2s, [{deny, blocked}, @@ -443,11 +441,13 @@ limit 1000 b/s. {shaper, normal, {maxrate, 1000}}. {access, c2s_shaper, [{none, admin}, {normal, all}]}. -{listen, [{5222, ejabberd_c2s, start, [{access, c2s}, - {shaper, c2s_shaper}]}, - {5269, ejabberd_s2s_in, start, []}, - {8888, ejabberd_service, start, - [{host, "conference.jabber.org", [{password, "secret"}]}]} +{listen, [{5222, ejabberd_c2s, [{access, c2s}, + {shaper, c2s_shaper}]}, + {5223, ejabberd_c2s, [{access, c2s}, + {ssl, [{certfile, "/path/to/ssl.pem"}]}]}, + {5269, ejabberd_s2s_in, []}, + {8888, ejabberd_service, + [{host, "conference.example.org", [{password, "secret"}]}]} ]}. </PRE> <!--TOC subsubsection Modules--> @@ -565,9 +565,9 @@ removed user is online, then he will be disconnected. Also user-related data <H4><A NAME="htoc20">3.2.2</A> Node <TT>online users</TT>: List of Online Users</H4><!--SEC END --> -<!--TOC subsubsection Node <TT>all users</TT>: List of Registered User--> +<!--TOC subsubsection Node <TT>all users</TT>: List of Registered Users--> -<H4><A NAME="htoc21">3.2.3</A> Node <TT>all users</TT>: List of Registered User</H4><!--SEC END --> +<H4><A NAME="htoc21">3.2.3</A> Node <TT>all users</TT>: List of Registered Users</H4><!--SEC END --> <BLOCKQUOTE><DIV ALIGN=center><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV> @@ -678,15 +678,16 @@ does not exist, then it is opened and registered.<BR> <H3><A NAME="htoc32">A.1</A> Common Options</H3><!--SEC END --> <A NAME="sec:modcommonopts"></A> -Following options used by many modules, so they described in separate section.<BR> +The following options are used by many modules, so they are described in +separate section.<BR> <BR> <!--TOC subsubsection Option <TT>iqdisc</TT>--> <H4><A NAME="htoc33">A.1.1</A> Option <TT>iqdisc</TT></H4><!--SEC END --> Many modules define handlers for processing IQ queries of different namespaces -to this server or to user (e. g. to <TT>myjabber.org</TT> or to -<TT>user@myjabber.org</TT>). This option defines processing discipline of +to this server or to user (e. g. to <TT>example.org</TT> or to +<TT>user@example.org</TT>). This option defines processing discipline of these queries. Possible values are: <DL COMPACT=compact><DT> <B><TT>no_queue</TT></B><DD> All queries of namespace with this processing @@ -721,7 +722,7 @@ Example: <PRE> {modules, [ ... - {mod_echo, [{host, "echo.myjabber.org"}]}, + {mod_echo, [{host, "echo.example.org"}]}, ... ]}. </PRE> @@ -745,12 +746,32 @@ Example: <H3><A NAME="htoc38">A.5</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> +<BR> +Options: +<DL COMPACT=compact><DT> +<B><TT>iqdisc</TT></B><DD> <TT>http://jabber.org/protocol/disco#items</TT> and + <TT>http://jabber.org/protocol/disco#info</TT> IQ queries processing discipline. +<DT><B><TT>extra_domains</TT></B><DD> List of domains that will be added to server + items reply +</DL> +Example: +<PRE> +{modules, [ + ... + {mod_disco, [[{extra_domains, ["jit.example.com", + "etc.example.com"]}]]}, + ... + ]}. +</PRE> <!--TOC subsection <TT>mod_stats</TT>--> <H3><A NAME="htoc39">A.6</A> <TT>mod_stats</TT></H3><!--SEC END --> <A NAME="sec:modstats"></A> -This module adds support of +This module adds support for <A HREF="http://www.jabber.org/jeps/jep-0039.html">JEP-0039</A> (Statistics Gathering).<BR> <BR> Options: @@ -816,8 +837,8 @@ Options: <A NAME="sec:i18nl10n"></A> Many modules supports <TT>xml:lang</TT> attribute inside IQ queries. E. g. -on figure <A HREF="#fig:discorus">6</A> (compare with figure <A HREF="#fig:disco">1</A>) showed reply -on following query: +on figure <A HREF="#fig:discorus">6</A> (compare it with figure <A HREF="#fig:disco">1</A>) showed +reply on following query: <PRE> <iq id='5' to='e.localhost' diff --git a/doc/guide.tex b/doc/guide.tex index 0c0a6d0fe..e07f93401 100644 --- a/doc/guide.tex +++ b/doc/guide.tex @@ -390,8 +390,6 @@ runned on them. Each element of list is a tuple with following elements: \begin{itemize} \item Port number; \item Module that serves this port; -\item Function in this module that starts connection (likely will be removed in - future versions of \ejabberd); \item Options to this module. \end{itemize} @@ -399,7 +397,7 @@ Currently three modules are implemented: \begin{description} \item[\texttt{ejabberd\_c2s}] This module serves C2S connections. - Following options defined: + The following options are defined: \begin{description} \item[\texttt{\{access, <access rule>\}}] This option defines access of users to this C2S port. Default value is ``\texttt{all}''. @@ -413,10 +411,10 @@ Currently three modules are implemented: \end{description} For example, the following configuration defines that C2S connections are -listened on port 5222 and denied for user ``\texttt{bad}'', S2S on port 5269 -and that service \texttt{conference.jabber.org} must be connected to port 8888 -with a password ``\texttt{secret}''. Also all users except admins have traffic -limit 1000\,b/s. +listened on port 5222 and 5223 (SSL) and denied for user ``\texttt{bad}'', S2S +on port 5269, and that service \texttt{conference.example.org} must be +connected to port 8888 with a password ``\texttt{secret}''. Also all users +except admins have traffic limit 1000\,b/s. \begin{verbatim} {acl, blocked, {user, "bad"}}. {access, c2s, [{deny, blocked}, @@ -424,11 +422,13 @@ limit 1000\,b/s. {shaper, normal, {maxrate, 1000}}. {access, c2s_shaper, [{none, admin}, {normal, all}]}. -{listen, [{5222, ejabberd_c2s, start, [{access, c2s}, - {shaper, c2s_shaper}]}, - {5269, ejabberd_s2s_in, start, []}, - {8888, ejabberd_service, start, - [{host, "conference.jabber.org", [{password, "secret"}]}]} +{listen, [{5222, ejabberd_c2s, [{access, c2s}, + {shaper, c2s_shaper}]}, + {5223, ejabberd_c2s, [{access, c2s}, + {ssl, [{certfile, "/path/to/ssl.pem"}]}]}, + {5269, ejabberd_s2s_in, []}, + {8888, ejabberd_service, + [{host, "conference.example.org", [{password, "secret"}]}]} ]}. \end{verbatim} @@ -539,7 +539,7 @@ removed user is online, then he will be disconnected. Also user-related data -\subsubsection{Node \texttt{all users}: List of Registered User} +\subsubsection{Node \texttt{all users}: List of Registered Users} \begin{figure}[htbp] \centering @@ -640,19 +640,17 @@ does not exist, then it is opened and registered. \section{Built-in Modules} \label{sec:modules} - - \subsection{Common Options} \label{sec:modcommonopts} -Following options used by many modules, so they described in separate section. - +The following options are used by many modules, so they are described in +separate section. \subsubsection{Option \texttt{iqdisc}} Many modules define handlers for processing IQ queries of different namespaces -to this server or to user (e.\,g.\ to \texttt{myjabber.org} or to -\texttt{user@myjabber.org}). This option defines processing discipline of +to this server or to user (e.\,g.\ to \texttt{example.org} or to +\texttt{user@example.org}). This option defines processing discipline of these queries. Possible values are: \begin{description} \item[\texttt{no\_queue}] All queries of namespace with this processing @@ -688,7 +686,7 @@ Example: \begin{verbatim} {modules, [ ... - {mod_echo, [{host, "echo.myjabber.org"}]}, + {mod_echo, [{host, "echo.example.org"}]}, ... ]}. \end{verbatim} @@ -713,12 +711,33 @@ Example: \subsection{\moddisco{}} \label{sec:moddisco} +This module adds support for +\footahref{http://www.jabber.org/jeps/jep-0030.html}{JEP-0030} (Service +Discovery). + +Options: +\begin{description} +\item[\texttt{iqdisc}] \ns{http://jabber.org/protocol/disco#items} and + \ns{http://jabber.org/protocol/disco#info} IQ queries processing discipline. +\item[\texttt{extra\_domains}] List of domains that will be added to server + items reply +\end{description} + +Example: +\begin{verbatim} +{modules, [ + ... + {mod_disco, [[{extra_domains, ["jit.example.com", + "etc.example.com"]}]]}, + ... + ]}. +\end{verbatim} \subsection{\modstats{}} \label{sec:modstats} -This module adds support of +This module adds support for \footahref{http://www.jabber.org/jeps/jep-0039.html}{JEP-0039} (Statistics Gathering). Options: @@ -784,8 +803,8 @@ Options: \label{sec:i18nl10n} Many modules supports \texttt{xml:lang} attribute inside IQ queries. E.\,g.\ -on figure~\ref{fig:discorus} (compare with figure~\ref{fig:disco}) showed reply -on following query: +on figure~\ref{fig:discorus} (compare it with figure~\ref{fig:disco}) showed +reply on following query: \begin{verbatim} <iq id='5' to='e.localhost' diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index a9a82d036..b18b02d6a 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -212,6 +212,10 @@ wait_for_auth({xmlstreamelement, El}, StateData) -> case ejabberd_auth:check_password( U, P, StateData#state.streamid, D) of true -> + ?INFO_MSG( + "(~w) Accepted legacy authentification for ~s", + [StateData#state.socket, + jlib:jid_to_string(JID)]), ejabberd_sm:open_session(U, R), Res = jlib:make_result_iq_reply(El), send_element(StateData, Res), @@ -230,12 +234,19 @@ wait_for_auth({xmlstreamelement, El}, StateData) -> pres_t = ?SETS:from_list(Ts), privacy_list = PrivList}}; _ -> + ?INFO_MSG( + "(~w) Failed legacy authentification for ~s", + [StateData#state.socket, + jlib:jid_to_string(JID)]), Err = jlib:make_error_reply( El, ?ERR_FORBIDDEN), send_element(StateData, Err), {next_state, wait_for_auth, StateData} end; _ -> + ?INFO_MSG("(~w) Forbidden legacy authentification for ~s", + [StateData#state.socket, + jlib:jid_to_string(JID)]), Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED), send_element(StateData, Err), {next_state, wait_for_auth, StateData} @@ -286,6 +297,9 @@ wait_for_sasl_auth({xmlstreamelement, El}, StateData) -> JID = #jid{user = U, resource = R} = jlib:string_to_jid( xml:get_attr_s(authzid, Props)), + ?INFO_MSG("(~w) Accepted authentification for ~s", + [StateData#state.socket, + jlib:jid_to_string(JID)]), {next_state, wait_for_stream, StateData#state{authentificated = true, user = U, @@ -350,6 +364,9 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) -> [{"xmlns", ?NS_SASL}], []}), JID = #jid{user = U, resource = R} = jlib:string_to_jid(xml:get_attr_s(authzid, Props)), + ?INFO_MSG("(~w) Accepted authentification for ~s", + [StateData#state.socket, + jlib:jid_to_string(JID)]), {next_state, wait_for_stream, StateData#state{authentificated = true, user = U, @@ -410,6 +427,9 @@ wait_for_session({xmlstreamelement, El}, StateData) -> JID = jlib:make_jid(U, StateData#state.server, R), case acl:match_rule(StateData#state.access, JID) of allow -> + ?INFO_MSG("(~w) Opened session for ~s", + [StateData#state.socket, + jlib:jid_to_string(JID)]), ejabberd_sm:open_session(U, R), Res = jlib:make_result_iq_reply(El), send_element(StateData, Res), @@ -425,6 +445,9 @@ wait_for_session({xmlstreamelement, El}, StateData) -> pres_t = ?SETS:from_list(Ts), privacy_list = PrivList}}; _ -> + ?INFO_MSG("(~w) Forbidden session for ~s", + [StateData#state.socket, + jlib:jid_to_string(JID)]), Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED), send_element(StateData, Err), {next_state, wait_for_session, StateData} @@ -700,6 +723,9 @@ terminate(Reason, StateName, StateData) -> "" -> ok; _ -> + ?INFO_MSG("(~w) Close session for ~s", + [StateData#state.socket, + jlib:jid_to_string(StateData#state.jid)]), ejabberd_sm:close_session(StateData#state.user, StateData#state.resource), From = StateData#state.jid, diff --git a/src/ejabberd_listener.erl b/src/ejabberd_listener.erl index 73ffc9a21..9de102be0 100644 --- a/src/ejabberd_listener.erl +++ b/src/ejabberd_listener.erl @@ -15,6 +15,8 @@ init_ssl/4 ]). +-include("ejabberd.hrl"). + start_link() -> supervisor:start_link({local, ejabberd_listeners}, ?MODULE, []). @@ -56,6 +58,13 @@ init(Port, Module, Opts) -> accept(ListenSocket, Module, Opts) -> case gen_tcp:accept(ListenSocket) of {ok, Socket} -> + case {inet:sockname(Socket), inet:peername(Socket)} of + {{ok, Addr}, {ok, PAddr}} -> + ?INFO_MSG("(~w) Accepted connection ~w -> ~w", + [Socket, PAddr, Addr]); + _ -> + ok + end, {ok, Pid} = Module:start({gen_tcp, Socket}, Opts), %{ok, Pid} = % supervisor:start_child( @@ -82,6 +91,13 @@ init_ssl(Port, Module, Opts, SSLOpts) -> accept_ssl(ListenSocket, Module, Opts) -> case ssl:accept(ListenSocket) of {ok, Socket} -> + case {ssl:sockname(Socket), ssl:peername(Socket)} of + {{ok, Addr}, {ok, PAddr}} -> + ?INFO_MSG("(~w) Accepted SSL connection ~w -> ~w", + [Socket, PAddr, Addr]); + _ -> + ok + end, apply(Module, start_link, [{ssl, Socket}, Opts]), accept_ssl(ListenSocket, Module, Opts) end. diff --git a/src/jd2ejd.erl b/src/jd2ejd.erl index 456fc0a65..6c3815d3b 100644 --- a/src/jd2ejd.erl +++ b/src/jd2ejd.erl @@ -93,9 +93,7 @@ wait_for_xdb(closed, StateData) -> xdb_data({xmlstreamelement, El}, StateData) -> {xmlelement, Name, Attrs, Els} = El, Server = StateData#state.server, - From = {StateData#state.user, - Server, - ""}, + From = jlib:make_jid(StateData#state.user, Server, ""), NewState = case xml:get_attr_s("xmlns", Attrs) of ?NS_AUTH -> @@ -109,9 +107,9 @@ xdb_data({xmlstreamelement, El}, StateData) -> mod_roster:set_items(StateData#state.user, El), StateData; ?NS_VCARD -> - Res = mod_vcard:process_local_iq(From, - {"", ?MYNAME, ""}, - {iq, "", set, ?NS_VCARD, El}), + Res = mod_vcard:process_sm_iq(From, + jlib:make_jid("", ?MYNAME, ""), + {iq, "", set, ?NS_VCARD, El}), StateData; "jabber:x:offline" -> process_offline(From, El), @@ -124,8 +122,22 @@ xdb_data({xmlstreamelement, El}, StateData) -> % io:format("user ~s~n", [User]), % StateData; XMLNS -> - io:format("jd2ejd: Unknown namespace \"~s\"~n", [XMLNS]), - StateData + case xml:get_attr_s("j_private_flag", Attrs) of + "1" -> + mod_private:process_local_iq( + From, + jlib:make_jid("", ?MYNAME, ""), + {iq, "", set, ?NS_PRIVATE, + {xmlelement, "query", [], + [jlib:remove_attr( + "j_private_flag", + jlib:remove_attr("xdbns", El))]}}), + StateData; + _ -> + io:format("jd2ejd: Unknown namespace \"~s\"~n", + [XMLNS]), + StateData + end end, {next_state, xdb_data, NewState}; @@ -191,7 +203,7 @@ handle_info(_, StateName, StateData) -> %% Returns: any %%---------------------------------------------------------------------- terminate(Reason, StateName, StateData) -> - StateData#state.pid ! {jd2ejd, exited}, + StateData#state.pid ! {jd2ejd, Reason}, ok. %%%---------------------------------------------------------------------- @@ -217,12 +229,20 @@ process_offline(To, {xmlelement, _, _, Els}) -> import_file(File) -> + clear_queue(), start(File), receive - M -> M - after 1000 -> ok + {jd2ejd, Result} -> Result + after 4000 -> timeout end. +clear_queue() -> + receive + {jd2ejd, _Result} -> clear_queue + after 0 -> ok + end. + + import_dir(Dir) -> {ok, Files} = file:list_dir(Dir), MsgFiles = lists:filter( diff --git a/src/mod_configure.erl b/src/mod_configure.erl index 95bf4e417..18cdbdc90 100644 --- a/src/mod_configure.erl +++ b/src/mod_configure.erl @@ -665,13 +665,16 @@ set_form(["config", "remusers"], Lang, XData) -> fun({Var, Vals}) -> case Vals of ["1"] -> - ejabberd_sm ! {route, {"", "", ""}, {Var, "", ""}, + ejabberd_sm ! {route, + jlib:make_jid("", "", ""), + jlib:make_jid(Var, "", ""), {xmlelement, "broadcast", [], [{exit, "User removed"}]}}, catch ejabberd_auth:remove_user(Var), catch mod_roster:remove_user(Var), catch mod_offline:remove_user(Var), - catch mod_vcard:remove_user(Var); + catch mod_vcard:remove_user(Var), + catch mod_private:remove_user(Var); _ -> ok end @@ -703,7 +706,7 @@ process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> deny -> {iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; allow -> - {User, _, _} = To, + #jid{user = User} = To, Lang = xml:get_tag_attr_s("xml:lang", SubEl), case Type of set -> @@ -790,5 +793,24 @@ get_sm_form(_, _, Lang) -> {error, ?ERR_SERVICE_UNAVAILABLE}. +set_sm_form(User, [], Lang, XData) -> + case lists:keysearch("action", 1, XData) of + {value, {_, ["edit"]}} -> + {error, ?ERR_FEATURE_NOT_IMPLEMENTED}; + {value, {_, ["remove"]}} -> + ejabberd_sm ! {route, + jlib:make_jid("", "", ""), + jlib:make_jid(User, "", ""), + {xmlelement, "broadcast", [], + [{exit, "User removed"}]}}, + catch ejabberd_auth:remove_user(User), + catch mod_roster:remove_user(User), + catch mod_offline:remove_user(User), + catch mod_vcard:remove_user(User), + catch mod_private:remove_user(User), + {result, []}; + _ -> + {error, ?ERR_BAD_REQUEST} + end; set_sm_form(_, _, Lang, XData) -> {error, ?ERR_SERVICE_UNAVAILABLE}. diff --git a/src/mod_disco.erl b/src/mod_disco.erl index a85553d3b..f658b58f8 100644 --- a/src/mod_disco.erl +++ b/src/mod_disco.erl @@ -19,7 +19,9 @@ process_sm_iq_items/3, process_sm_iq_info/3, register_feature/1, - unregister_feature/1]). + unregister_feature/1, + register_extra_domain/1, + unregister_extra_domain/1]). -include("ejabberd.hrl"). -include("jlib.hrl"). @@ -42,6 +44,9 @@ start(Opts) -> register_feature("iq"), register_feature("presence"), register_feature("presence-invisible"), + catch ets:new(disco_extra_domains, [named_table, ordered_set, public]), + ExtraDomains = gen_mod:get_opt(extra_domains, Opts, []), + lists:foreach(fun register_extra_domain/1, ExtraDomains), ok. stop() -> @@ -59,6 +64,14 @@ unregister_feature(Feature) -> catch ets:new(disco_features, [named_table, ordered_set, public]), ets:delete(disco_features, Feature). +register_extra_domain(Domain) -> + catch ets:new(disco_extra_domains, [named_table, ordered_set, public]), + ets:insert(disco_extra_domains, {Domain}). + +unregister_extra_domain(Domain) -> + catch ets:new(disco_extra_domains, [named_table, ordered_set, public]), + ets:delete(disco_extra_domains, Domain). + process_local_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) -> Lang = xml:get_tag_attr_s("xml:lang", SubEl), case Type of @@ -180,10 +193,11 @@ process_local_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) -> feature_to_xml({Feature}) -> {xmlelement, "feature", [{"var", Feature}], []}. +domain_to_xml({Domain}) -> + {xmlelement, "item", [{"jid", Domain}], []}; domain_to_xml(Domain) -> {xmlelement, "item", [{"jid", Domain}], []}. - -define(NODE(Name, Node), {xmlelement, "item", [{"jid", Server}, @@ -193,12 +207,14 @@ domain_to_xml(Domain) -> get_services_only() -> lists:map(fun domain_to_xml/1, - ejabberd_router:dirty_get_all_routes()). + ejabberd_router:dirty_get_all_routes()) ++ + lists:map(fun domain_to_xml/1, ets:tab2list(disco_extra_domains)). get_local_items([], Server, Lang) -> Domains = lists:map(fun domain_to_xml/1, - ejabberd_router:dirty_get_all_routes()), + ejabberd_router:dirty_get_all_routes()) ++ + lists:map(fun domain_to_xml/1, ets:tab2list(disco_extra_domains)), {result, Domains ++ [?NODE("Configuration", "config"), diff --git a/src/mod_private.erl b/src/mod_private.erl index 8b091433f..a4ec97d1d 100644 --- a/src/mod_private.erl +++ b/src/mod_private.erl @@ -14,7 +14,8 @@ -export([start/1, stop/0, - process_local_iq/3]). + process_local_iq/3, + remove_user/1]). -include("ejabberd.hrl"). -include("jlib.hrl"). @@ -95,3 +96,20 @@ get_data(LUser, [El | Els], Res) -> _ -> get_data(LUser, Els, Res) end. + + +remove_user(User) -> + LUser = jlib:nodeprep(User), + F = fun() -> + lists:foreach( + fun({U, _} = Key) -> + if + U == LUser -> + mnesia:delete({private_storage, Key}); + true -> + ok + end + end, mnesia:all_keys(private_storage)) + end, + mnesia:transaction(F). + diff --git a/src/stringprep/stringprep_drv.c b/src/stringprep/stringprep_drv.c index 906ea6207..43dd2b87a 100644 --- a/src/stringprep/stringprep_drv.c +++ b/src/stringprep/stringprep_drv.c @@ -37,7 +37,7 @@ static void stringprep_erl_stop(ErlDrvData handle) * library */ -void canonical_ordering(int *str, int len) +static void canonical_ordering(int *str, int len) { int i, j, t; int last, next; @@ -232,13 +232,6 @@ static int stringprep_erl_control(ErlDrvData drv_data, } info = GetUniCharInfo(uc); - //if(info & prohibit) { - // *rbuf = rstring; - // driver_free(str32); - // return 1; - //} - - //printf("Got %x\r\n", uc); if(!(info & B1Mask)) { @@ -247,34 +240,10 @@ static int stringprep_erl_control(ErlDrvData drv_data, { ruc = uc + GetDelta(info); ADD_DECOMP(ruc); - - //info = GetUniCharDecompInfo(ruc); - //if(info >= 0) { - // decomp_len = GetDecompLen(info); - // decomp_shift = GetDecompShift(info); - // for(j = 0; j < decomp_len; j++) { - // ADD_UCHAR32(str32, str32pos, str32len, - // decompList[decomp_shift + j]); - // } - //} else { - // ADD_UCHAR32(str32, str32pos, str32len, ruc); - //} - - //info = GetUniCharDecompInfo(ruc); - //if(info >= 0) { - // printf("Decomposition %x: ", ruc); - // for(j = 0; j < GetDecompLen(info); j++) { - // printf("%x ", decompList[GetDecompShift(info) + j]); - // } - // printf("\r\n"); - //} - - //ADD_UCHAR(ruc); } else { mc = GetMC(info); for(j = 1; j <= mc[0]; j++) { ruc = mc[j]; - //printf("Char %x cclass %d\r\n", ruc, GetUniCharCClass(ruc)); ADD_DECOMP(ruc); } } @@ -292,19 +261,8 @@ static int stringprep_erl_control(ErlDrvData drv_data, return 1; } - //printf("\r\n"); - //printf("DECOMPOSED:\t"); - //for(i = 0; i < str32pos; i++) - // printf("%4x ", str32[i]); - //printf("\r\n"); - canonical_ordering(str32, str32pos); - //printf("ORDERED:\t"); - //for(i = 0; i < str32pos; i++) - // printf("%4x ", str32[i]); - //printf("\r\n"); - comp_pos = 1; comp_starter_pos = 0; ch1 = str32[0]; @@ -314,7 +272,6 @@ static int stringprep_erl_control(ErlDrvData drv_data, { ch2 = str32[i]; cclass2 = GetUniCharCClass(ch2); - //printf("Compose: %x + %x = %x\r\n", ch1, ch2, compose(ch1, ch2)); if(cclass1 == 0 && cclass2 > cclass_prev && (ruc = compose(ch1, ch2))) { ch1 = ruc; } else { @@ -332,11 +289,6 @@ static int stringprep_erl_control(ErlDrvData drv_data, str32[comp_starter_pos] = ch1; str32pos = comp_pos; - //printf("COMPOSED:\t"); - //for(i = 0; i < str32pos; i++) - // printf("%4x ", str32[i]); - //printf("\r\n"); - for(i = 0; i < str32pos; i++) { ruc = str32[i]; @@ -349,9 +301,6 @@ static int stringprep_erl_control(ErlDrvData drv_data, ADD_UCHAR(ruc); } - //printf("Compose: %x\r\n", compose(0x438, 0x301)); - //printf("Pos: %d\r\n", pos); - rstring[0] = 1; *rbuf = rstring; driver_free(str32); diff --git a/src/stringprep/uni_norm.c b/src/stringprep/uni_norm.c index d95ad5ba0..fe7281b46 100644 --- a/src/stringprep/uni_norm.c +++ b/src/stringprep/uni_norm.c @@ -77,9 +77,8 @@ static unsigned char cclassPageMap[] = { }; /* - * The groupMap is indexed by combining the alternate page number with - * the page offset and returns a group number that identifies a unique - * set of character attributes. + * The cclassGroupMap is indexed by combining the alternate page number with + * the page offset and returns a combining class number. */ static unsigned char cclassGroupMap[] = { @@ -297,9 +296,9 @@ static unsigned char decompPageMap[] = { }; /* - * The groupMap is indexed by combining the alternate page number with - * the page offset and returns a group number that identifies a unique - * set of character attributes. + * The decompGroupMap is indexed by combining the alternate page number with + * the page offset and returns a group number that identifies a length and + * shift of decomposition sequence in decompList */ static int decompGroupMap[] = { @@ -839,7 +838,7 @@ static int decompGroupMap[] = { }; /* - * Each group represents a unique set of character attributes. The attributes... + * List of decomposition sequences */ static int decompList[] = { @@ -1295,8 +1294,6 @@ static int decompList[] = { * Unicode character tables. */ -//#define GetUniCharInfo(ch) (groups[groupMap[(pageMap[(((int)(ch)) & 0xffff) >> CCLASS_OFFSET_BITS] << CCLASS_OFFSET_BITS) | ((ch) & ((1 << CCLASS_OFFSET_BITS)-1))]]) - #define GetUniCharDecompInfo(ch) (decompGroupMap[(decompPageMap[(((int)(ch)) & 0xffff) >> DECOMP_OFFSET_BITS] << DECOMP_OFFSET_BITS) | ((ch) & ((1 << DECOMP_OFFSET_BITS)-1))]) #define GetDecompShift(info) ((info) & 0xffff) @@ -1556,7 +1553,7 @@ static int compGroupMap[] = { }; /* - * ... + * Lists of compositions for characters that appears only in one composition */ static int compFirstList[][2] = { @@ -1612,6 +1609,10 @@ static int compSecondList[][2] = { {1575, 1570}, {1575, 1573} }; +/* + * Compositions matrix + */ + static int compBothList[144][37] = { { 8179, 8060, 974, 0, 8032, 0, 8033, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/src/stringprep/uni_parse2.tcl b/src/stringprep/uni_parse2.tcl index 2f3ef7ecd..968f262b7 100644 --- a/src/stringprep/uni_parse2.tcl +++ b/src/stringprep/uni_parse2.tcl @@ -423,9 +423,8 @@ static unsigned char cclassPageMap\[\] = {" puts $f "}; /* - * The groupMap is indexed by combining the alternate page number with - * the page offset and returns a group number that identifies a unique - * set of character attributes. + * The cclassGroupMap is indexed by combining the alternate page number with + * the page offset and returns a combining class number. */ static unsigned char cclassGroupMap\[\] = {" @@ -476,9 +475,9 @@ static unsigned char decompPageMap\[\] = {" puts $f "}; /* - * The groupMap is indexed by combining the alternate page number with - * the page offset and returns a group number that identifies a unique - * set of character attributes. + * The decompGroupMap is indexed by combining the alternate page number with + * the page offset and returns a group number that identifies a length and + * shift of decomposition sequence in decompList */ static int decompGroupMap\[\] = {" @@ -502,7 +501,7 @@ static int decompGroupMap\[\] = {" puts $f "}; /* - * Each group represents a unique set of character attributes. The attributes... + * List of decomposition sequences */ static int decompList\[\] = {" @@ -529,8 +528,6 @@ static int decompList\[\] = {" * Unicode character tables. */ -//#define GetUniCharInfo(ch) (groups\[groupMap\[(pageMap\[(((int)(ch)) & 0xffff) >> CCLASS_OFFSET_BITS\] << CCLASS_OFFSET_BITS) | ((ch) & ((1 << CCLASS_OFFSET_BITS)-1))\]\]) - #define GetUniCharDecompInfo(ch) (decompGroupMap\[(decompPageMap\[(((int)(ch)) & 0xffff) >> DECOMP_OFFSET_BITS\] << DECOMP_OFFSET_BITS) | ((ch) & ((1 << DECOMP_OFFSET_BITS)-1))\]) #define GetDecompShift(info) ((info) & 0xffff) @@ -588,7 +585,7 @@ static int compGroupMap\[\] = {" puts $f "}; /* - * ... + * Lists of compositions for characters that appears only in one composition */ static int compFirstList\[\]\[2\] = {" @@ -627,6 +624,10 @@ static int compSecondList\[\]\[2\] = {" puts $f $line puts $f "}; +/* + * Compositions matrix + */ + static int compBothList\[[llength $comp_x_list]\]\[[llength $comp_y_list]\] = {" set lastx [expr {[llength $comp_x_list] - 1}] set lasty [expr {[llength $comp_y_list] - 1}] |