]> granicus.if.org Git - ejabberd/commitdiff
*** empty log message ***
authorAlexey Shchepin <alexey@process-one.net>
Sat, 18 Jan 2003 19:42:48 +0000 (19:42 +0000)
committerAlexey Shchepin <alexey@process-one.net>
Sat, 18 Jan 2003 19:42:48 +0000 (19:42 +0000)
SVN Revision: 43

14 files changed:
src/acl.erl [new file with mode: 0644]
src/ejabberd.cfg
src/ejabberd.erl
src/ejabberd.hrl
src/ejabberd_config.erl
src/ejabberd_local.erl
src/ejabberd_router.erl
src/ejabberd_sm.erl
src/jlib.erl
src/mod_disco.erl
src/mod_stats.erl
src/mod_time.erl [new file with mode: 0644]
src/mod_version.erl [new file with mode: 0644]
src/namespaces.hrl

diff --git a/src/acl.erl b/src/acl.erl
new file mode 100644 (file)
index 0000000..109d4ed
--- /dev/null
@@ -0,0 +1,51 @@
+%%%----------------------------------------------------------------------
+%%% File    : acl.erl
+%%% Author  : Alexey Shchepin <alexey@sevcom.net>
+%%% Purpose : 
+%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
+%%% Id      : $Id$
+%%%----------------------------------------------------------------------
+
+-module(acl).
+-author('alexey@sevcom.net').
+-vsn('$Revision$ ').
+
+-export([start/0, add/2, match_rule/2, match_acl/2]).
+
+-include("ejabberd.hrl").
+
+start() ->
+    ets:new(acls, [bag, named_table, public]).
+
+
+add(ACLName, ACLData) ->
+    ets:insert(acls, {ACLName, ACLData}).
+
+match_rule(Rule, JID) ->
+    ACLs = ejabberd_config:get_option(Rule),
+    match_acls(ACLs, JID).
+
+match_acls([], _) ->
+    deny;
+match_acls([{Access, ACL} | ACLs], JID) ->
+    case match_acl(ACL, JID) of
+       true ->
+           Access;
+       _ ->
+           match_acls(ACLs, JID)
+    end.
+
+match_acl(ACL, JID) ->
+    {User, Server, Resource} = jlib:jid_tolower(JID),
+    lists:any(fun({_, Spec}) ->
+                     case Spec of
+                         all ->
+                             true;
+                         {user, U} ->
+                             (U == User) and (?MYNAME == Server);
+                         {user, U, S} ->
+                             (U == User) and (S == Server);
+                         {server, S} ->
+                             S == Server
+                     end
+             end, ets:lookup(acls, ACL)).
index 74f6869ae782f557d7657fcb2f4963c49e4cc378..538c7918f204035a071f287d1f28356ab84c4c54 100644 (file)
@@ -1,5 +1,12 @@
 % $Id$
 
+{acl, admin, {user, "aleksey"}}.
+{acl, admin, {user, "ermine"}}.
+{acl, jabberorg, {server, "jabber.org"}}.
+{acl, aleksey, {user, "aleksey", "jabber.ru"}}.
+
+{disco_admin, [{allow, admin},
+              {deny, all}]}.
 
 {host, "e.localhost"}.
 
index c2845cebec0a632e858a4af1e8d258da5235b51f..e02773594276127d63cf59aadbec637101695318 100644 (file)
@@ -19,7 +19,7 @@ start() ->
 
 init() ->
     register(ejabberd, self()),
-    erlang:system_flag(fullsweep_after, 0),
+    %erlang:system_flag(fullsweep_after, 0),
     error_logger:logfile({open, ?ERROR_LOG_PATH}),
     randoms:start(),
     ok = erl_ddll:load_driver(".", expat_erl),
@@ -27,6 +27,7 @@ init() ->
     db_init(),
     sha:start(),
     translate:start(),
+    acl:start(),
     ejabberd_config:start(),
     ejabberd_auth:start(),
     ejabberd_router:start(),
index 13dd063bd6c0b75d629d62488717dfc83d709c7e..44adc0db4b4633d496c193d6237fe27ef9100cf7 100644 (file)
@@ -6,6 +6,8 @@
 %%% Id      : $Id$
 %%%----------------------------------------------------------------------
 
+-define(VERSION, "0.0.1-alpha").
+
 %-define(ejabberd_debug, true).
 %-define(DBGFSM, true).
 
index 0c147090042f5b74a62a44b3a57a3782b79d07e2..1bae8a9fddab8d3e4b645d24d16278a876dfa81b 100644 (file)
@@ -22,13 +22,19 @@ start() ->
 load_file(File) ->
     case file:consult(File) of
        {ok, Terms} ->
-           lists:foreach(fun({Opt, Val}) ->
-                                 ets:insert(ejabberd_config, {Opt, Val})
-                         end, Terms);
+           lists:foreach(fun process_term/1, Terms);
        {error, Reason} ->
            exit(file:format_error(Reason))
     end.
 
+process_term(Term) ->
+    case Term of
+       {acl, ACLName, ACLData} ->
+           acl:add(ACLName, ACLData);
+       {Opt, Val} ->
+           ets:insert(ejabberd_config, {Opt, Val})
+    end.
+
 
 get_option(Opt) ->
     case ets:lookup(ejabberd_config, Opt) of
index 1b970447a3795fe6dda56a0400165d1971f51028..f96aab3ee55be4710de3ff8800ffb67ecdc18bfc 100644 (file)
@@ -28,6 +28,8 @@ start() ->
     mod_offline:start(),
     mod_echo:start(),
     mod_private:start(),
+    mod_time:start(),
+    mod_version:start(),
     ok.
 
 init() ->
@@ -60,10 +62,8 @@ do_route(State, From, To, Packet) ->
                "message" ->
                    ok;
                "presence" ->
-                   % TODO
                    ok;
                _ ->
-                   % DROP
                    ok
            end;
        {"", _, _} ->
index 8fda160c07debaaff298922c4aec2af29ed2b4f0..0ef1a93e2a845ad2e58fc8383f8e04494ee7069d 100644 (file)
@@ -101,9 +101,10 @@ loop() ->
 do_route(From, To, Packet) ->
     ?DEBUG("route~n\tfrom ~p~n\tto ~p~n\tpacket ~p~n", [From, To, Packet]),
     {DstNode, DstDomain, DstResourse} = To,
-    case mnesia:dirty_read({local_route, DstDomain}) of
+    LDstDomain = jlib:tolower(DstDomain),
+    case mnesia:dirty_read({local_route, LDstDomain}) of
        [] ->
-           case mnesia:dirty_read({route, DstDomain}) of
+           case mnesia:dirty_read({route, LDstDomain}) of
                [] ->
                    ejabberd_s2s ! {route, From, To, Packet};
                [R] ->
index 725c98c7c9083422a725c217e9a3f62840a932df..a86dce479f5af831717609cbd62db5153b98476b 100644 (file)
@@ -15,6 +15,7 @@
         set_presence/3,
         unset_presence/2,
         dirty_get_sessions_list/0,
+        dirty_get_my_sessions_list/0,
         register_iq_handler/3]).
 
 -include_lib("mnemosyne/include/mnemosyne.hrl").
@@ -250,8 +251,8 @@ do_route(From, To, Packet) ->
                    ok
            end;
        _ ->
-           UR = {User, Resource},
-           Sess = mnesia:dirty_read({session, UR}),
+           LUR = {jlib:tolower(User), Resource},
+           Sess = mnesia:dirty_read({session, LUR}),
            case Sess of
                [] ->
                    if
@@ -261,7 +262,7 @@ do_route(From, To, Packet) ->
                            ?DEBUG("packet droped~n", [])
                    end;
                [Ses] ->
-                   case mnesia:dirty_read({mysession, UR}) of
+                   case mnesia:dirty_read({mysession, LUR}) of
                        [] ->
                            Node = Ses#session.node,
                            ?DEBUG("sending to node ~p~n", [Node]),
@@ -344,6 +345,9 @@ get_user_present_resources(User) ->
 dirty_get_sessions_list() ->
     mnesia:dirty_all_keys(session).
 
+dirty_get_my_sessions_list() ->
+    mnesia:dirty_all_keys(mysession).
+
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
index 2dbd3f4d7d6360658f42fe4c35868c766dfc05c4..3cf7ed577c33a4f3049592701e48c00155be67da 100644 (file)
@@ -27,6 +27,7 @@
         is_iq_request_type/1,
         iq_to_xml/1,
         parse_xdata_submit/1,
+        timestamp_to_iso/1,
         timestamp_to_xml/1]).
 
 -include("namespaces.hrl").
@@ -293,6 +294,11 @@ parse_xdata_values([_ | Els], Res) ->
     parse_xdata_values(Els, Res).
 
 
+timestamp_to_iso({{Year, Month, Day}, {Hour, Minute, Second}}) ->
+    lists:flatten(
+      io_lib:format("~4..0w~2..0w~2..0wT~2..0w:~2..0w:~2..0w",
+                   [Year, Month, Day, Hour, Minute, Second])).
+
 timestamp_to_xml({{Year, Month, Day}, {Hour, Minute, Second}}) ->
     {xmlelement, "x",
      [{"xmlns", ?NS_DELAY},
@@ -300,3 +306,4 @@ timestamp_to_xml({{Year, Month, Day}, {Hour, Minute, Second}}) ->
                  io_lib:format("~4..0w~2..0w~2..0wT~2..0w:~2..0w:~2..0w",
                                [Year, Month, Day, Hour, Minute, Second]))}],
      []}.
+
index 9284e1419392c946841c06fef66f88eaef39c635..aee3fc13c19e1a0e21d9251dcd1b1bebf0eee393 100644 (file)
@@ -53,55 +53,19 @@ process_local_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
                                            [{"code", "405"}],
                                            [{xmlcdata, "Not Allowed"}]}]};
        get ->
-           case string:tokens(xml:get_tag_attr_s("node", SubEl), "/") of
-               [] ->
-                   Domains =
-                       lists:map(fun domain_to_xml/1,
-                                 ejabberd_router:dirty_get_all_routes()),
-                   {iq, ID, result, XMLNS,
-                    [{xmlelement,
-                      "query",
-                      [{"xmlns", ?NS_DISCO_ITEMS}],
-                      Domains ++
-                      [{xmlelement, "item",
-                        [{"jid", jlib:jid_to_string(To)},
-                         {"name", translate:translate(Lang, "Online Users")},
-                         {"node", "online users"}], []},
-                       {xmlelement, "item",
-                        [{"jid", jlib:jid_to_string(To)},
-                         {"name", translate:translate(Lang, "All Users")},
-                         {"node", "all users"}], []},
-                       {xmlelement, "item",
-                        [{"jid", jlib:jid_to_string(To)},
-                         {"name", translate:translate(
-                                    Lang, "Outgoing S2S connections")},
-                         {"node", "outgoing s2s"}], []}
-                      ]}]};
-               ["online users"] ->
-                   {iq, ID, result, XMLNS,
-                    [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
-                      get_online_users()
-                     }]};
-               ["all users"] ->
-                   {iq, ID, result, XMLNS,
-                    [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
-                      get_all_users()
-                     }]};
-               ["outgoing s2s"] ->
-                   {iq, ID, result, XMLNS,
-                    [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
-                      get_outgoing_s2s(Lang)
-                     }]};
-               ["outgoing s2s", Host] ->
+           Node = string:tokens(xml:get_tag_attr_s("node", SubEl), "/"),
+
+           case get_local_items(Node, jlib:jid_to_string(To), Lang) of
+               {result, Res} ->
                    {iq, ID, result, XMLNS,
                     [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
-                      get_outgoing_s2s(Lang, Host)
+                      Res
                      }]};
-               _ ->
+               {error, Code, Desc} ->
                    {iq, ID, error, XMLNS,
                     [SubEl, {xmlelement, "error",
-                             [{"code", "501"}],
-                             [{xmlcdata, "Not Implemented"}]}]}
+                             [{"code", Code}],
+                             [{xmlcdata, Desc}]}]}
            end
     end.
 
@@ -129,6 +93,19 @@ process_local_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
                ["online users"] -> ?EMPTY_INFO_RESULT;
                ["all users"] -> ?EMPTY_INFO_RESULT;
                ["outgoing s2s" | _] -> ?EMPTY_INFO_RESULT;
+               ["running nodes"] -> ?EMPTY_INFO_RESULT;
+               ["stopped nodes"] -> ?EMPTY_INFO_RESULT;
+               ["running nodes", ENode] ->
+                   {iq, ID, result, XMLNS, [{xmlelement,
+                                             "query",
+                                             [{"xmlns", ?NS_DISCO_INFO}],
+                                             [{xmlelement, "identity",
+                                               [{"category", "ejabberd"},
+                                                {"type", "node"},
+                                                {"name", ENode}], []},
+                                              feature_to_xml({?NS_STATS})
+                                             ]
+                                            }]};
                _ ->
                    {iq, ID, error, XMLNS,
                     [SubEl, {xmlelement, "error",
@@ -145,6 +122,51 @@ domain_to_xml(Domain) ->
     {xmlelement, "item", [{"jid", Domain}], []}.
 
 
+-define(TOP_NODE(Name, Node),
+       {xmlelement, "item",
+        [{"jid", Server},
+         {"name", translate:translate(Lang, Name)},
+         {"node", Node}], []}).
+
+
+get_local_items([], Server, Lang) ->
+    Domains =
+       lists:map(fun domain_to_xml/1,
+                 ejabberd_router:dirty_get_all_routes()),
+    {result,
+       Domains ++
+       [?TOP_NODE("Online Users",             "online users"),
+       ?TOP_NODE("All Users",                "all users"),
+       ?TOP_NODE("Outgoing S2S connections", "outgoing s2s"),
+       ?TOP_NODE("Running Nodes",            "running nodes"),
+       ?TOP_NODE("Stopped Nodes",            "stopped nodes")
+       ]};
+
+get_local_items(["online users"], Server, Lang) ->
+    {result, get_online_users()};
+
+get_local_items(["all users"], Server, Lang) ->
+    {result, get_all_users()};
+
+get_local_items(["outgoing s2s"], Server, Lang) ->
+    {result, get_outgoing_s2s(Lang)};
+
+get_local_items(["running nodes"], Server, Lang) ->
+    {result, get_running_nodes(Lang)};
+
+get_local_items(["stopped nodes"], Server, Lang) ->
+    {result, get_stopped_nodes(Lang)};
+
+get_local_items(["running nodes", _], Server, Lang) ->
+    {result, []};
+
+get_local_items(_, _, _) ->
+    {error, "501", "Not Implemented"}.
+
+
+
+
+
 get_online_users() ->
     case catch ejabberd_sm:dirty_get_sessions_list() of
        {'EXIT', Reason} ->
@@ -208,6 +230,44 @@ get_outgoing_s2s(Lang, To) ->
     end.
 
 
+get_running_nodes(Lang) ->
+    case catch mnesia:system_info(running_db_nodes) of
+       {'EXIT', Reason} ->
+           [];
+       DBNodes ->
+           lists:map(
+             fun(N) ->
+                     S = atom_to_list(N),
+                     {xmlelement, "item",
+                      [{"jid", ?MYNAME},
+                       {"node", "running nodes/" ++ S},
+                       {"name", S}],
+                      []}
+             end, lists:sort(DBNodes))
+    end.
+
+get_stopped_nodes(Lang) ->
+    case catch (lists:usort(mnesia:system_info(db_nodes) ++
+                           mnesia:system_info(extra_db_nodes)) --
+               mnesia:system_info(running_db_nodes)) of
+       {'EXIT', Reason} ->
+           [];
+       DBNodes ->
+           lists:map(
+             fun(N) ->
+                     S = atom_to_list(N),
+                     {xmlelement, "item",
+                      [{"jid", ?MYNAME},
+                       {"node", "stopped nodes/" ++ S},
+                       {"name", S}],
+                      []}
+             end, lists:sort(DBNodes))
+    end.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 process_sm_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
     {User, _, _} = To,
     case Type of
index 15f433b1daf61383bc08885854e396ee0034c383..3eff2621aed83c3aaa78c3b3d6f6b6ad1d85bcc6 100644 (file)
@@ -31,49 +31,16 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
            Node = string:tokens(xml:get_tag_attr_s("node", SubEl), "/"),
            Names = get_names(Els, []),
            
-           {T, Res} = get_local_stats(Node, Names),
-           case T of
-               result ->
-                   {iq, ID, result, ?NS_STATS, Res};
-               error ->
-                   {iq, ID, error, ?NS_STATS, [SubEl ++ Res]}
+           case get_local_stats(Node, Names) of
+               {result, Res} ->
+                   {iq, ID, result, XMLNS,
+                    [{xmlelement, "query", [{"xmlns", XMLNS}], Res}]};
+               {error, Code, Desc} ->
+                   {iq, ID, error, XMLNS,
+                    [SubEl, {xmlelement, "error",
+                             [{"code", Code}],
+                             [{xmlcdata, Desc}]}]}
            end
-
-           %case Node of
-               %[] ->
-               %    {iq, ID, result, XMLNS,
-               %     [{xmlelement,
-               %       "query",
-               %       [{"xmlns", ?NS_STATS}],
-               %       [{xmlelement, "stat", [{"name", "time/uptime"}], []},
-               %       {xmlelement, "stat", [{"name", "time/cputime"}], []}
-               %       ]}]};
-               %["online users"] ->
-               %    {iq, ID, result, XMLNS,
-               %     [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
-               %       get_online_users()
-               %      }]};
-               %["all users"] ->
-               %    {iq, ID, result, XMLNS,
-               %     [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
-               %       get_all_users()
-               %      }]};
-               %["outgoing s2s"] ->
-               %    {iq, ID, result, XMLNS,
-               %     [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
-               %       get_outgoing_s2s(Lang)
-               %      }]};
-               %["outgoing s2s", Host] ->
-               %    {iq, ID, result, XMLNS,
-               %     [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
-               %       get_outgoing_s2s(Lang, Host)
-               %      }]};
-               %_ ->
-               %    {iq, ID, error, XMLNS,
-               %     [SubEl, {xmlelement, "error",
-               %             [{"code", "501"}],
-               %             [{xmlcdata, "Not Implemented"}]}]}
-           %end
     end.
 
 
@@ -91,31 +58,39 @@ get_names([_ | Els], Res) ->
     get_names(Els, Res).
 
 
+-define(STAT(Name), {xmlelement, "stat", [{"name", Name}], []}).
+
 get_local_stats([], []) ->
     {result,
-     [{xmlelement,
-       "query",
-       [{"xmlns", ?NS_STATS}],
-       [{xmlelement, "stat", [{"name", "time/uptime"}], []},
-       {xmlelement, "stat", [{"name", "time/cputime"}], []},
-       {xmlelement, "stat", [{"name", "users/online"}], []},
-       {xmlelement, "stat", [{"name", "users/total"}], []}
-       ]}]};
+     [?STAT("users/online"),
+      ?STAT("users/total")
+     ]};
+
 get_local_stats([], Names) ->
+    {result, lists:map(fun(Name) -> get_local_stat([], Name) end, Names)};
+
+get_local_stats(["running nodes", _], []) ->
     {result,
-     [{xmlelement,
-       "query",
-       [{"xmlns", ?NS_STATS}],
-       lists:map(fun(Name) -> get_local_stat([], Name) end, Names)
-      }]};
+     [?STAT("time/uptime"),
+      ?STAT("time/cputime"),
+      ?STAT("users/online")
+     ]};
+
+get_local_stats(["running nodes", ENode], Names) ->
+    case search_running_node(ENode) of
+       false ->
+           {error, "404", "Not Found"};
+       Node ->
+           {result,
+            lists:map(fun(Name) -> get_node_stat(Node, Name) end, Names)}
+    end;
+
 get_local_stats(_, _) ->
-    {error,
-     [{xmlelement, "error",
-       [{"code", "501"}],
-       [{xmlcdata, "Not Implemented"}]}]}.
+    {error, "501", "Not Implemented"}.
+
 
 
--define(STAT(Val, Unit),
+-define(STATVAL(Val, Unit),
        {xmlelement, "stat",
         [{"name", Name},
          {"units", Unit},
@@ -130,25 +105,70 @@ get_local_stats(_, _) ->
           [{xmlcdata, Desc}]}]}).
 
 
-get_local_stat([], Name) when Name == "time/uptime" ->
-    ?STAT(io_lib:format("~.3f", [element(1, statistics(wall_clock))/1000]),
-         "seconds");
-get_local_stat([], Name) when Name == "time/cputime" ->
-    ?STAT(io_lib:format("~.3f", [element(1, statistics(runtime))/1000]),
-         "seconds");
+%get_local_stat([], Name) when Name == "time/uptime" ->
+%    ?STATVAL(io_lib:format("~.3f", [element(1, statistics(wall_clock))/1000]),
+%           "seconds");
+%get_local_stat([], Name) when Name == "time/cputime" ->
+%    ?STATVAL(io_lib:format("~.3f", [element(1, statistics(runtime))/1000]),
+%           "seconds");
 get_local_stat([], Name) when Name == "users/online" ->
     case catch ejabberd_sm:dirty_get_sessions_list() of
        {'EXIT', Reason} ->
            ?STATERR("500", "Internal Server Error");
        Users ->
-           ?STAT(integer_to_list(length(Users)), "users")
+           ?STATVAL(integer_to_list(length(Users)), "users")
     end;
 get_local_stat([], Name) when Name == "users/total" ->
     case catch ejabberd_auth:dirty_get_registered_users() of
        {'EXIT', Reason} ->
            ?STATERR("500", "Internal Server Error");
        Users ->
-           ?STAT(integer_to_list(length(Users)), "users")
+           ?STATVAL(integer_to_list(length(Users)), "users")
     end;
 get_local_stat(_, Name) ->
     ?STATERR("404", "Not Found").
+
+
+
+get_node_stat(Node, Name) when Name == "time/uptime" ->
+    case catch rpc:call(Node, erlang, statistics, [wall_clock]) of
+       {badrpc, Reason} ->
+           ?STATERR("500", "Internal Server Error");
+       CPUTime ->
+           ?STATVAL(
+              io_lib:format("~.3f", [element(1, CPUTime)/1000]), "seconds")
+    end;
+
+get_node_stat(Node, Name) when Name == "time/cputime" ->
+    case catch rpc:call(Node, erlang, statistics, [runtime]) of
+       {badrpc, Reason} ->
+           ?STATERR("500", "Internal Server Error");
+       RunTime ->
+           ?STATVAL(
+              io_lib:format("~.3f", [element(1, RunTime)/1000]), "seconds")
+    end;
+
+get_node_stat(Node, Name) when Name == "users/online" ->
+    case catch rpc:call(Node, ejabberd_sm, dirty_get_my_sessions_list, []) of
+       {badrpc, Reason} ->
+           ?STATERR("500", "Internal Server Error");
+       Users ->
+           ?STATVAL(integer_to_list(length(Users)), "users")
+    end;
+get_node_stat(_, Name) ->
+    ?STATERR("404", "Not Found").
+
+
+search_running_node(SNode) ->
+    search_running_node(SNode, mnesia:system_info(running_db_nodes)).
+
+search_running_node(_, []) ->
+    false;
+search_running_node(SNode, [Node | Nodes]) ->
+    case atom_to_list(Node) of
+       SNode ->
+           Node;
+       _ ->
+           search_running_node(SNode, Nodes)
+    end.
+
diff --git a/src/mod_time.erl b/src/mod_time.erl
new file mode 100644 (file)
index 0000000..2820f62
--- /dev/null
@@ -0,0 +1,45 @@
+%%%----------------------------------------------------------------------
+%%% File    : mod_time.erl
+%%% Author  : Alexey Shchepin <alexey@sevcom.net>
+%%% Purpose : 
+%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
+%%% Id      : $Id$
+%%%----------------------------------------------------------------------
+
+-module(mod_time).
+-author('alexey@sevcom.net').
+-vsn('$Revision$ ').
+
+-export([start/0,
+        process_local_iq/3]).
+
+-include("ejabberd.hrl").
+-include("namespaces.hrl").
+
+
+
+
+start() ->
+    ejabberd_local:register_iq_handler(?NS_TIME,
+                                      ?MODULE, process_local_iq).
+
+
+
+process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
+    case Type of
+       set ->
+           {iq, ID, error, XMLNS,
+            [SubEl, {xmlelement, "error",
+                     [{"code", "405"}],
+                     [{xmlcdata, "Not Allowed"}]}]};
+       get ->
+           UTC = jlib:timestamp_to_iso(calendar:universal_time()),
+           {iq, ID, result, XMLNS,
+            [{xmlelement, "query",
+              [{"xmlns", ?NS_TIME}],
+              [{xmlelement, "utc", [],
+                [{xmlcdata, UTC}]}
+              ]}]}
+    end.
+
+
diff --git a/src/mod_version.erl b/src/mod_version.erl
new file mode 100644 (file)
index 0000000..c79b5fb
--- /dev/null
@@ -0,0 +1,64 @@
+%%%----------------------------------------------------------------------
+%%% File    : mod_version.erl
+%%% Author  : Alexey Shchepin <alexey@sevcom.net>
+%%% Purpose : 
+%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
+%%% Id      : $Id$
+%%%----------------------------------------------------------------------
+
+-module(mod_version).
+-author('alexey@sevcom.net').
+-vsn('$Revision$ ').
+
+-export([start/0,
+        process_local_iq/3]).
+
+-include("ejabberd.hrl").
+-include("namespaces.hrl").
+
+
+
+
+start() ->
+    ejabberd_local:register_iq_handler(?NS_VERSION,
+                                      ?MODULE, process_local_iq).
+
+
+
+process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
+    case Type of
+       set ->
+           {iq, ID, error, XMLNS,
+            [SubEl, {xmlelement, "error",
+                     [{"code", "405"}],
+                     [{xmlcdata, "Not Allowed"}]}]};
+       get ->
+           OSType = case os:type() of
+                        {Osfamily, Osname} ->
+                            atom_to_list(Osfamily) ++ "/" ++
+                                atom_to_list(Osname);
+                        Osfamily ->
+                            atom_to_list(Osfamily)
+                    end,
+           OSVersion = case os:version() of
+                           {Major, Minor, Release} ->
+                               lists:flatten(
+                                 io_lib:format("~w.~w.~w",
+                                               [Major, Minor, Release]));
+                           VersionString ->
+                               VersionString
+                       end,
+           OS = OSType ++ " " ++ OSVersion,
+           {iq, ID, result, XMLNS,
+            [{xmlelement, "query",
+              [{"xmlns", ?NS_VERSION}],
+              [{xmlelement, "name", [],
+                [{xmlcdata, "ejabberd"}]},
+               {xmlelement, "version", [],
+                [{xmlcdata, ?VERSION}]},
+               {xmlelement, "os", [],
+                [{xmlcdata, OS}]}
+              ]}]}
+    end.
+
+
index 21835b43d14322f7018d9ee55622acbb6b0da331..712348a9114cd2b50833cce8eec62ed4ef05aa69 100644 (file)
@@ -6,16 +6,18 @@
 %%%----------------------------------------------------------------------
 
 -define(NS_DISCO_ITEMS, "http://jabber.org/protocol/disco#items").
--define(NS_DISCO_INFO, "http://jabber.org/protocol/disco#info").
--define(NS_VCARD, "vcard-temp").
--define(NS_AUTH, "jabber:iq:auth").
--define(NS_REGISTER, "jabber:iq:register").
--define(NS_SEARCH, "jabber:iq:search").
--define(NS_ROSTER, "jabber:iq:roster").
--define(NS_PRIVATE, "jabber:iq:private").
--define(NS_XDATA, "jabber:x:data").
--define(NS_DELAY, "jabber:x:delay").
--define(NS_EVENT, "jabber:x:event").
--define(NS_STATS, "http://jabber.org/protocol/stats").
+-define(NS_DISCO_INFO,  "http://jabber.org/protocol/disco#info").
+-define(NS_VCARD,       "vcard-temp").
+-define(NS_AUTH,        "jabber:iq:auth").
+-define(NS_REGISTER,    "jabber:iq:register").
+-define(NS_SEARCH,      "jabber:iq:search").
+-define(NS_ROSTER,      "jabber:iq:roster").
+-define(NS_PRIVATE,     "jabber:iq:private").
+-define(NS_VERSION,     "jabber:iq:version").
+-define(NS_TIME,        "jabber:iq:time").
+-define(NS_XDATA,       "jabber:x:data").
+-define(NS_DELAY,       "jabber:x:delay").
+-define(NS_EVENT,       "jabber:x:event").
+-define(NS_STATS,       "http://jabber.org/protocol/stats").