mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
* src/mod_last_odbc.erl: Added store_last_info/4 function (thanks
to Sergei Golovan) * src/mod_last.erl: Likewise * src/jd2ejd.erl: Support for exporting iq:last information, better error handling (thanks to Sergei Golovan) * src/ejabberd_ctl.erl: Added "import-file" and "import-dir" commands (thanks to Sergei Golovan) SVN Revision: 358
This commit is contained in:
parent
6b1e56f786
commit
dbb248247b
10
ChangeLog
10
ChangeLog
@ -1,5 +1,15 @@
|
||||
2005-05-23 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
* src/mod_last_odbc.erl: Added store_last_info/4 function (thanks
|
||||
to Sergei Golovan)
|
||||
* src/mod_last.erl: Likewise
|
||||
|
||||
* src/jd2ejd.erl: Support for exporting iq:last information,
|
||||
better error handling (thanks to Sergei Golovan)
|
||||
|
||||
* src/ejabberd_ctl.erl: Added "import-file" and "import-dir"
|
||||
commands (thanks to Sergei Golovan)
|
||||
|
||||
* doc/guide.tex: Updated (thanks to Sergei Golovan)
|
||||
* doc/dev.tex: Likewise
|
||||
* doc/disco.png: Likewise
|
||||
|
46
doc/dev.html
46
doc/dev.html
@ -61,34 +61,38 @@
|
||||
|
||||
<A NAME="sec:intro"></A>
|
||||
<TT>ejabberd</TT> is a Free and Open Source fault-tolerant distributed Jabber
|
||||
server. It is writen mostly in Erlang.<BR>
|
||||
server. It is written mostly in Erlang.<BR>
|
||||
<BR>
|
||||
The main features of <TT>ejabberd</TT> is:
|
||||
The main features of <TT>ejabberd</TT> are:
|
||||
<UL><LI>
|
||||
Works on most of popular platforms: *nix (tested on Linux and FreeBSD)
|
||||
and Win32
|
||||
<LI>Distributed: You can run <TT>ejabberd</TT> on a cluster of machines and all of
|
||||
them will serve one Jabber domain.
|
||||
Works on most of popular platforms: *nix (tested on Linux, FreeBSD and
|
||||
NetBSD) and Win32
|
||||
<LI>Distributed: You can run <TT>ejabberd</TT> on a cluster of machines to let all of
|
||||
them serve one Jabber domain.
|
||||
<LI>Fault-tolerance: You can setup an <TT>ejabberd</TT> cluster so that all the
|
||||
information required for a properly working service will be stored
|
||||
permanently on more than one node. This means that if one of the nodes
|
||||
crashes, then the others will continue working without disruption.
|
||||
You can also add or replace more nodes ``on the fly''.
|
||||
<LI>Built-in <A HREF="http://www.jabber.org/jeps/jep-0045.html">Multi-User
|
||||
Chat</A> service
|
||||
You can also add or replace nodes ``on the fly''.
|
||||
<LI>Support for virtual hosting
|
||||
<LI>Built-in <A HREF="http://www.jabber.org/jeps/jep-0045.html">Multi-User Chat</A> service
|
||||
<LI>Built-in IRC transport
|
||||
<LI>Built-in
|
||||
<A HREF="http://www.jabber.org/jeps/jep-0060.html">Publish-Subscribe</A>
|
||||
service
|
||||
<LI>Built-in <A HREF="http://www.jabber.org/jeps/jep-0060.html">Publish-Subscribe</A> service
|
||||
<LI>Built-in Jabber Users Directory service based on users vCards
|
||||
<LI>Support for
|
||||
<A HREF="http://www.jabber.org/jeps/jep-0030.html">JEP-0030</A>
|
||||
(Service Discovery).
|
||||
<LI>Support for
|
||||
<A HREF="http://www.jabber.org/jeps/jep-0039.html">JEP-0039</A>
|
||||
(Statistics Gathering).
|
||||
<LI>Support for <TT>xml:lang</TT> attribute in many XML elements
|
||||
<LI>Built-in web-based administration interface
|
||||
<LI>Built-in <A HREF="http://www.jabber.org/jeps/jep-0025.html">HTTP Polling</A> service
|
||||
<LI>SSL support
|
||||
<LI>Support for LDAP authentication
|
||||
<LI>Ability to interface with external components (JIT, MSN-t, Yahoo-t, etc.)
|
||||
<LI>Migration from jabberd14 is possible
|
||||
<LI>Mostly XMPP-compliant
|
||||
<LI>Support for <A HREF="http://www.jabber.org/jeps/jep-0030.html">Service Discovery</A>.
|
||||
<LI>Support for <A HREF="http://www.jabber.org/jeps/jep-0039.html">Statistics Gathering</A>.
|
||||
<LI>Support for <TT>xml:lang</TT>
|
||||
</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-->
|
||||
|
||||
<H3><A NAME="htoc2">1.1</A> How it works</H3><!--SEC END -->
|
||||
@ -166,13 +170,13 @@ XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
|
||||
CDATA = {xmlcdata, string()}
|
||||
</PRE>E. g. this stanza:
|
||||
<PRE>
|
||||
<message to='test@conference.e.localhost' type='groupchat'>
|
||||
<message to='test@conference.example.org' type='groupchat'>
|
||||
<body>test</body>
|
||||
</message>
|
||||
</PRE>represented as following structure:
|
||||
<PRE>
|
||||
{xmlelement, "message",
|
||||
[{"to", "test@conference.e.localhost"},
|
||||
[{"to", "test@conference.example.org"},
|
||||
{"type", "groupchat"}],
|
||||
[{xmlelement, "body",
|
||||
[],
|
||||
|
@ -4,7 +4,7 @@
|
||||
<HEAD><TITLE>Ejabberd Installation and Operation Guide</TITLE>
|
||||
|
||||
<META http-equiv="Content-Type" content="text/html; charset=ISO8859-1">
|
||||
<META name="GENERATOR" content="hevea 1.07">
|
||||
<META name="GENERATOR" content="hevea 1.06">
|
||||
</HEAD>
|
||||
<BODY >
|
||||
<!--HEVEA command line is: /usr/bin/hevea -charset ISO8859-1 guide.tex -->
|
||||
@ -21,7 +21,7 @@
|
||||
<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>
|
||||
|
||||
<H3 ALIGN=center>April 18, 2005</H3><DIV ALIGN=center>
|
||||
<H3 ALIGN=center>May 23, 2005</H3><DIV ALIGN=center>
|
||||
|
||||
<IMG SRC="logo.png">
|
||||
|
||||
@ -141,8 +141,8 @@ Works on most of popular platforms: *nix (tested on Linux, FreeBSD and
|
||||
<LI>Ability to interface with external components (JIT, MSN-t, Yahoo-t, etc.)
|
||||
<LI>Migration from jabberd14 is possible
|
||||
<LI>Mostly XMPP-compliant
|
||||
<LI>Support for <A HREF="http://www.jabber.org/jeps/jep-0030.html">JEP-0030</A> (Service Discovery).
|
||||
<LI>Support for <A HREF="http://www.jabber.org/jeps/jep-0039.html">JEP-0039</A> (Statistics Gathering).
|
||||
<LI>Support for <A HREF="http://www.jabber.org/jeps/jep-0030.html">Service Discovery</A>.
|
||||
<LI>Support for <A HREF="http://www.jabber.org/jeps/jep-0039.html">Statistics Gathering</A>.
|
||||
<LI>Support for <TT>xml:lang</TT>
|
||||
</UL>
|
||||
The misfeatures of <TT>ejabberd</TT> are:
|
||||
@ -391,7 +391,7 @@ declarations of ACL in config file have following syntax:
|
||||
</PRE><DT><B><TT>{user_regexp, <regexp>, <server>}</TT></B><DD> Matches user with name
|
||||
that matches <TT><regexp></TT> and from server <TT><server></TT>. Example:
|
||||
<PRE>
|
||||
{acl, tests, {user, "^test", "localhost"}}.
|
||||
{acl, tests, {user, "^test", "example.org"}}.
|
||||
</PRE><DT><B><TT>{server_regexp, <regexp>}</TT></B><DD> Matches any JID from server that
|
||||
matches <TT><regexp></TT>. Example:
|
||||
<PRE>
|
||||
@ -518,7 +518,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">JEP-0025</A> (HTTP Polling)
|
||||
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>
|
||||
@ -629,7 +629,7 @@ Example:
|
||||
{mod_vcard, []},
|
||||
{mod_offline, []},
|
||||
{mod_announce, [{access, announce}]},
|
||||
{mod_echo, [{host, "echo.localhost"}]},
|
||||
{mod_echo, [{host, "echo.example.org"}]},
|
||||
{mod_private, []},
|
||||
{mod_irc, []},
|
||||
{mod_muc, []},
|
||||
@ -823,9 +823,8 @@ Replicating of table makes lookup in this table faster on this node,
|
||||
but writing will be slower. And of course if machine with one of
|
||||
replicas is down, other replicas will be used.<BR>
|
||||
<BR>
|
||||
Also section ``5.3 Table Fragmentation''
|
||||
<A HREF="http://www.erlang.se/doc/doc-5.4/lib/mnesia-4.2/doc/html/index.html">here</A>
|
||||
can be useful.<BR>
|
||||
Also section 5.3 (Table Fragmentation) of
|
||||
<A HREF="http://www.erlang.se/doc/doc-5.4/lib/mnesia-4.2/doc/html/index.html">Mnesia Reference Manual</A> can be useful.<BR>
|
||||
<BR>
|
||||
(alt) Same as in previous item, but for other tables.<BR>
|
||||
<BR>
|
||||
@ -1426,7 +1425,7 @@ All built-in modules support <TT>xml:lang</TT> attribute inside IQ queries.
|
||||
E. g. on figure <A HREF="#fig:discorus">2</A> showed the reply on the following query:
|
||||
<PRE>
|
||||
<iq id='5'
|
||||
to='e.localhost'
|
||||
to='example.org'
|
||||
type='get'
|
||||
xml:lang='ru'>
|
||||
<query xmlns='http://jabber.org/protocol/disco#items'/>
|
||||
|
@ -82,7 +82,7 @@ discipline (see~\ref{sec:modiqdiscoption}).}
|
||||
\author{Alexey Shchepin \\
|
||||
\ahrefurl{mailto:alexey@sevcom.net} \\
|
||||
\ahrefurl{xmpp:aleksey@jabber.ru}}
|
||||
\date{April 18, 2005}
|
||||
\date{May 23, 2005}
|
||||
|
||||
\begin{document}
|
||||
\begin{titlepage}
|
||||
|
@ -173,6 +173,34 @@ process(Node, ["install-fallback", Path]) ->
|
||||
?STATUS_BADRPC
|
||||
end;
|
||||
|
||||
process(Node, ["import-file", Path]) ->
|
||||
case rpc:call(Node, jd2ejd, import_file, [Path]) of
|
||||
ok ->
|
||||
?STATUS_SUCCESS;
|
||||
{error, Reason} ->
|
||||
io:format("Can't import jabberd 1.4 spool file ~p at node ~p: ~p~n",
|
||||
[filename:absname(Path), Node, Reason]),
|
||||
?STATUS_ERROR;
|
||||
{badrpc, Reason} ->
|
||||
io:format("Can't import jabberd 1.4 spool file ~p at node ~p: ~p~n",
|
||||
[filename:absname(Path), Node, Reason]),
|
||||
?STATUS_BADRPC
|
||||
end;
|
||||
|
||||
process(Node, ["import-dir", Path]) ->
|
||||
case rpc:call(Node, jd2ejd, import_dir, [Path]) of
|
||||
ok ->
|
||||
?STATUS_SUCCESS;
|
||||
{error, Reason} ->
|
||||
io:format("Can't import jabberd 1.4 spool dir ~p at node ~p: ~p~n",
|
||||
[filename:absname(Path), Node, Reason]),
|
||||
?STATUS_ERROR;
|
||||
{badrpc, Reason} ->
|
||||
io:format("Can't import jabberd 1.4 spool dir ~p at node ~p: ~p~n",
|
||||
[filename:absname(Path), Node, Reason]),
|
||||
?STATUS_BADRPC
|
||||
end;
|
||||
|
||||
process(Node, ["registered-users"]) ->
|
||||
case rpc:call(Node, ejabberd_auth, dirty_get_registered_users, []) of
|
||||
Users when is_list(Users) ->
|
||||
@ -217,12 +245,14 @@ print_usage() ->
|
||||
" restart\t\t\trestart ejabberd~n"
|
||||
" reopen-log\t\t\treopen log file~n"
|
||||
" register user server password\tregister a user~n"
|
||||
" unregister user server\t\tunregister a user~n"
|
||||
" backup file\t\t\tstore a database backup in file~n"
|
||||
" unregister user server\tunregister a user~n"
|
||||
" backup file\t\t\tstore a database backup to file~n"
|
||||
" restore file\t\t\trestore a database backup from file~n"
|
||||
" install-fallback file\t\tinstall a database fallback from file~n"
|
||||
" dump file\t\t\tdump a database in a text file~n"
|
||||
" dump file\t\t\tdump a database to a text file~n"
|
||||
" load file\t\t\trestore a database from a text file~n"
|
||||
" import-file file\t\timport user data from jabberd 1.4 spool file~n"
|
||||
" import-dir dir\t\timport user data from jabberd 1.4 spool directory~n"
|
||||
" registered-users\t\tlist all registered users~n"
|
||||
" delete-expired-messages\tdelete expired offline messages from database~n"
|
||||
"~n"
|
||||
|
@ -37,19 +37,23 @@ import_file(File) ->
|
||||
{'EXIT', Reason} ->
|
||||
?ERROR_MSG(
|
||||
"Error while processing file \"~s\": ~p~n",
|
||||
[File, Reason]);
|
||||
[File, Reason]),
|
||||
{error, Reason};
|
||||
_ ->
|
||||
ok
|
||||
end;
|
||||
{error, Reason} ->
|
||||
?ERROR_MSG("Can't parse file \"~s\": ~p~n",
|
||||
[File, Reason])
|
||||
[File, Reason]),
|
||||
{error, Reason}
|
||||
end;
|
||||
{error, Reason} ->
|
||||
?ERROR_MSG("Can't read file \"~s\": ~p~n", [File, Reason])
|
||||
?ERROR_MSG("Can't read file \"~s\": ~p~n", [File, Reason]),
|
||||
{error, Reason}
|
||||
end;
|
||||
false ->
|
||||
?ERROR_MSG("Incorrect user/server name in file \"~s\"~n", [File])
|
||||
?ERROR_MSG("Illegal user/server name in file \"~s\"~n", [File]),
|
||||
{error, "illegal user/server"}
|
||||
end.
|
||||
|
||||
|
||||
@ -65,11 +69,15 @@ import_dir(Dir) ->
|
||||
false
|
||||
end
|
||||
end, Files),
|
||||
lists:foreach(
|
||||
fun(FN) ->
|
||||
import_file(filename:join([Dir, FN]))
|
||||
end, MsgFiles),
|
||||
ok.
|
||||
lists:foldl(
|
||||
fun(FN, A) ->
|
||||
Res = import_file(filename:join([Dir, FN])),
|
||||
case {A, Res} of
|
||||
{ok, ok} -> ok;
|
||||
{ok, _} -> {error, "see ejabberd log for details"};
|
||||
_ -> A
|
||||
end
|
||||
end, ok, MsgFiles).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% Internal functions
|
||||
@ -99,6 +107,14 @@ xdb_data(User, Server, {xmlelement, _Name, Attrs, _Els} = El) ->
|
||||
?NS_ROSTER ->
|
||||
catch mod_roster:set_items(User, Server, El),
|
||||
ok;
|
||||
?NS_LAST ->
|
||||
TimeStamp = xml:get_attr_s("last", Attrs),
|
||||
Status = xml:get_tag_cdata(El),
|
||||
catch mod_last:store_last_info(User,
|
||||
Server,
|
||||
list_to_integer(TimeStamp),
|
||||
Status),
|
||||
ok;
|
||||
?NS_VCARD ->
|
||||
catch mod_vcard:process_sm_iq(
|
||||
From,
|
||||
|
@ -17,6 +17,7 @@
|
||||
process_local_iq/3,
|
||||
process_sm_iq/3,
|
||||
on_presence_update/4,
|
||||
store_last_info/4,
|
||||
remove_user/2]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
@ -118,18 +119,21 @@ get_last(IQ, SubEl, LUser, LServer) ->
|
||||
|
||||
|
||||
on_presence_update(User, Server, _Resource, Status) ->
|
||||
{MegaSecs, Secs, _MicroSecs} = now(),
|
||||
TimeStamp = MegaSecs * 1000000 + Secs,
|
||||
store_last_info(User, Server, TimeStamp, Status).
|
||||
|
||||
store_last_info(User, Server, TimeStamp, Status) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
US = {LUser, LServer},
|
||||
{MegaSecs, Secs, _MicroSecs} = now(),
|
||||
TimeStamp = MegaSecs * 1000000 + Secs,
|
||||
F = fun() ->
|
||||
mnesia:write(#last_activity{us = US,
|
||||
timestamp = TimeStamp,
|
||||
status = Status})
|
||||
end,
|
||||
mnesia:transaction(F).
|
||||
|
||||
|
||||
|
||||
remove_user(User, Server) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
|
@ -16,7 +16,8 @@
|
||||
stop/0,
|
||||
process_local_iq/3,
|
||||
process_sm_iq/3,
|
||||
on_presence_update/3,
|
||||
on_presence_update/4,
|
||||
store_last_info/4,
|
||||
remove_user/1]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
@ -120,10 +121,13 @@ get_last(IQ, SubEl, LUser) ->
|
||||
|
||||
|
||||
|
||||
on_presence_update(User, _Resource, Status) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
on_presence_update(User, Server, _Resource, Status) ->
|
||||
{MegaSecs, Secs, _MicroSecs} = now(),
|
||||
TimeStamp = MegaSecs * 1000000 + Secs,
|
||||
store_last_info(User, Server, TimeStamp, Status).
|
||||
|
||||
store_last_info(User, Server, TimeStamp, Status) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
Seconds = ejabberd_odbc:escape(integer_to_list(TimeStamp)),
|
||||
State = ejabberd_odbc:escape(Status),
|
||||
|
Loading…
Reference in New Issue
Block a user