From dbb248247b5dbc0113ea9e272ea2b9495ed34041 Mon Sep 17 00:00:00 2001 From: Alexey Shchepin Date: Mon, 23 May 2005 19:47:57 +0000 Subject: [PATCH] * 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 --- ChangeLog | 10 ++++++++++ doc/dev.html | 46 +++++++++++++++++++++++-------------------- doc/guide.html | 21 ++++++++++---------- doc/guide.tex | 2 +- src/ejabberd_ctl.erl | 36 ++++++++++++++++++++++++++++++--- src/jd2ejd.erl | 34 +++++++++++++++++++++++--------- src/mod_last.erl | 10 +++++++--- src/mod_last_odbc.erl | 10 +++++++--- 8 files changed, 118 insertions(+), 51 deletions(-) diff --git a/ChangeLog b/ChangeLog index 687e90161..6a69517bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2005-05-23 Alexey Shchepin + * 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 diff --git a/doc/dev.html b/doc/dev.html index ad12f39dd..48a96e7a7 100644 --- a/doc/dev.html +++ b/doc/dev.html @@ -61,34 +61,38 @@ ejabberd is a Free and Open Source fault-tolerant distributed Jabber -server. It is writen mostly in Erlang.
+server. It is written mostly in Erlang.

-The main features of ejabberd is: +The main features of ejabberd are: +ejabberd is a Free and Open Source fault-tolerant distributed Jabber +server. It is written mostly in Erlang.
+

1.1  How it works

@@ -166,13 +170,13 @@ XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]} CDATA = {xmlcdata, string()} E. g. this stanza:
-<message to='test@conference.e.localhost' type='groupchat'>
+<message to='test@conference.example.org' type='groupchat'>
   <body>test</body>
 </message>
 
represented as following structure:
 {xmlelement, "message",
-    [{"to", "test@conference.e.localhost"},
+    [{"to", "test@conference.example.org"},
      {"type", "groupchat"}],
     [{xmlelement, "body",
          [],
diff --git a/doc/guide.html b/doc/guide.html
index 802d73d2d..61e37ee70 100644
--- a/doc/guide.html
+++ b/doc/guide.html
@@ -4,7 +4,7 @@
 Ejabberd Installation and Operation Guide
 
 
-
+
 
 
 
@@ -21,7 +21,7 @@
 mailto:alexey@sevcom.net
xmpp:aleksey@jabber.ru -

April 18, 2005

+

May 23, 2005

@@ -141,8 +141,8 @@ Works on most of popular platforms: *nix (tested on Linux, FreeBSD and
  • Ability to interface with external components (JIT, MSN-t, Yahoo-t, etc.)
  • Migration from jabberd14 is possible
  • Mostly XMPP-compliant -
  • Support for JEP-0030 (Service Discovery). -
  • Support for JEP-0039 (Statistics Gathering). +
  • Support for Service Discovery. +
  • Support for Statistics Gathering.
  • Support for xml:lang The misfeatures of ejabberd are: @@ -391,7 +391,7 @@ declarations of ACL in config file have following syntax:
  • {user_regexp, <regexp>, <server>}
    Matches user with name that matches <regexp> and from server <server>. Example:
    -{acl, tests, {user, "^test", "localhost"}}.
    +{acl, tests, {user, "^test", "example.org"}}.
     
    {server_regexp, <regexp>}
    Matches any JID from server that matches <regexp>. Example:
    @@ -518,7 +518,7 @@ The following additional options are defined for ejabberd_service
     
    The following options are defined:
    - http_poll
    This option enables HTTP Polling + http_poll
    This option enables JEP-0025 (HTTP Polling) support. It is available then at http://server:port/http-poll/.

    web_admin
    This option enables web-based interface for ejabberd @@ -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.

    -Also section ``5.3 Table Fragmentation'' - here - can be useful.
    +Also section 5.3 (Table Fragmentation) of + Mnesia Reference Manual can be useful.

    (alt) Same as in previous item, but for other tables.

    @@ -1426,7 +1425,7 @@ All built-in modules support xml:lang attribute inside IQ queries. E. g. on figure 2 showed the reply on the following query:
       <iq id='5'
    -      to='e.localhost'
    +      to='example.org'
           type='get'
           xml:lang='ru'>
         <query xmlns='http://jabber.org/protocol/disco#items'/>
    diff --git a/doc/guide.tex b/doc/guide.tex
    index 487906d78..235b26646 100644
    --- a/doc/guide.tex
    +++ b/doc/guide.tex
    @@ -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}
    diff --git a/src/ejabberd_ctl.erl b/src/ejabberd_ctl.erl
    index 4d9d35135..216466625 100644
    --- a/src/ejabberd_ctl.erl
    +++ b/src/ejabberd_ctl.erl
    @@ -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"
    diff --git a/src/jd2ejd.erl b/src/jd2ejd.erl
    index 6f2152b97..86e36a038 100644
    --- a/src/jd2ejd.erl
    +++ b/src/jd2ejd.erl
    @@ -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,
    diff --git a/src/mod_last.erl b/src/mod_last.erl
    index 8a1bb0539..33c9727a1 100644
    --- a/src/mod_last.erl
    +++ b/src/mod_last.erl
    @@ -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),
    diff --git a/src/mod_last_odbc.erl b/src/mod_last_odbc.erl
    index ef3c656eb..e7577ed40 100644
    --- a/src/mod_last_odbc.erl
    +++ b/src/mod_last_odbc.erl
    @@ -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),
    -- 
    2.50.0