diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl index 496bf3442..a03209e87 100644 --- a/src/ejabberd_local.erl +++ b/src/ejabberd_local.erl @@ -23,6 +23,7 @@ start() -> mod_register:start(), mod_roster:start(), mod_disco:start(), + mod_stats:start(), mod_vcard:start(), mod_offline:start(), ok. diff --git a/src/mod_offline.erl b/src/mod_offline.erl index a08e05a01..42c8973dd 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -15,7 +15,7 @@ -include("namespaces.hrl"). --record(offline_msg, {user, timestamp, from, to, packet}). +-record(offline_msg, {user, timestamp, from, to, packet}). start() -> @@ -30,7 +30,7 @@ store_packet(From, To, Packet) -> true -> {User, Server, Resource} = To, LUser = jlib:tolower(User), - TimeStamp = calendar:universal_time(), + TimeStamp = now(), F = fun() -> mnesia:write(#offline_msg{user = LUser, timestamp = TimeStamp, @@ -105,7 +105,9 @@ resend_offline_messages(User) -> R#offline_msg.to, {xmlelement, Name, Attrs, Els ++ - [jlib:timestamp_to_xml(R#offline_msg.timestamp)]}} + [jlib:timestamp_to_xml( + calendar:now_to_universal_time( + R#offline_msg.timestamp))]}} end, lists:keysort(#offline_msg.timestamp, Rs)); _ -> diff --git a/src/mod_register.erl b/src/mod_register.erl index 3f4c1c42e..3901f58fb 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -70,13 +70,18 @@ process_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> try_register(User, Password) -> - case ejabberd_auth:try_register(User, Password) of - {atomic, ok} -> - ok; - {atomic, exists} -> - {error, "400", "Bad Request"}; - {error, Reason} -> - {error, "500", "Internal Server Error"} + case jlib:string_to_jid(User ++ "@" ++ "x") of + error -> + {error, "406", "Not Acceptable"}; + _ -> + case ejabberd_auth:try_register(User, Password) of + {atomic, ok} -> + ok; + {atomic, exists} -> + {error, "400", "Bad Request"}; + {error, Reason} -> + {error, "500", "Internal Server Error"} + end end. diff --git a/src/mod_stats.erl b/src/mod_stats.erl new file mode 100644 index 000000000..15f433b1d --- /dev/null +++ b/src/mod_stats.erl @@ -0,0 +1,154 @@ +%%%---------------------------------------------------------------------- +%%% File : mod_stats.erl +%%% Author : Alexey Shchepin +%%% Purpose : +%%% Created : 11 Jan 2003 by Alexey Shchepin +%%% Id : $Id$ +%%%---------------------------------------------------------------------- + +-module(mod_stats). +-author('alexey@sevcom.net'). +-vsn('$Revision$ '). + +-export([start/0, + process_local_iq/3]). + +-include("namespaces.hrl"). + +start() -> + ejabberd_local:register_iq_handler(?NS_STATS, ?MODULE, process_local_iq). + + +process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> + Lang = xml:get_tag_attr_s("xml:lang", SubEl), + case Type of + set -> + {iq, ID, error, XMLNS, [SubEl, {xmlelement, "error", + [{"code", "405"}], + [{xmlcdata, "Not Allowed"}]}]}; + get -> + {xmlelement, _, Attrs, Els} = 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]} + 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. + + +get_names([], Res) -> + Res; +get_names([{xmlelement, "stat", Attrs, _} | Els], Res) -> + Name = xml:get_attr_s("name", Attrs), + case Name of + "" -> + get_names(Els, Res); + _ -> + get_names(Els, [Name | Res]) + end; +get_names([_ | Els], Res) -> + get_names(Els, Res). + + +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"}], []} + ]}]}; +get_local_stats([], Names) -> + {result, + [{xmlelement, + "query", + [{"xmlns", ?NS_STATS}], + lists:map(fun(Name) -> get_local_stat([], Name) end, Names) + }]}; +get_local_stats(_, _) -> + {error, + [{xmlelement, "error", + [{"code", "501"}], + [{xmlcdata, "Not Implemented"}]}]}. + + +-define(STAT(Val, Unit), + {xmlelement, "stat", + [{"name", Name}, + {"units", Unit}, + {"value", Val} + ], []}). + +-define(STATERR(Code, Desc), + {xmlelement, "stat", + [{"name", Name}], + [{xmlelement, "error", + [{"code", Code}], + [{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 == "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") + 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") + end; +get_local_stat(_, Name) -> + ?STATERR("404", "Not Found"). diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index 6ddf90949..ff341a99b 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -103,7 +103,7 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> [{xmlcdata, "Erlang Jabber Server\n" "Copyright (c) 2002, 2003 Alexey Shchepin"}]}, {xmlelement, "BDAY", [], - [{xmlcdata, "20021116"}]} + [{xmlcdata, "2002-11-16"}]} ]}]} end. diff --git a/src/namespaces.hrl b/src/namespaces.hrl index 671fe86aa..0786a5974 100644 --- a/src/namespaces.hrl +++ b/src/namespaces.hrl @@ -13,5 +13,6 @@ -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").