aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ejabberd_local.erl1
-rw-r--r--src/mod_offline.erl8
-rw-r--r--src/mod_register.erl19
-rw-r--r--src/mod_stats.erl154
-rw-r--r--src/mod_vcard.erl2
-rw-r--r--src/namespaces.hrl1
6 files changed, 174 insertions, 11 deletions
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 <alexey@sevcom.net>
+%%% Purpose :
+%%% Created : 11 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
+%%% 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").