diff --git a/src/acl.erl b/src/acl.erl new file mode 100644 index 000000000..109d4edd6 --- /dev/null +++ b/src/acl.erl @@ -0,0 +1,51 @@ +%%%---------------------------------------------------------------------- +%%% File : acl.erl +%%% Author : Alexey Shchepin +%%% Purpose : +%%% Created : 18 Jan 2003 by Alexey Shchepin +%%% 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)). diff --git a/src/ejabberd.cfg b/src/ejabberd.cfg index 74f6869ae..538c7918f 100644 --- a/src/ejabberd.cfg +++ b/src/ejabberd.cfg @@ -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"}. diff --git a/src/ejabberd.erl b/src/ejabberd.erl index c2845cebe..e02773594 100644 --- a/src/ejabberd.erl +++ b/src/ejabberd.erl @@ -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(), diff --git a/src/ejabberd.hrl b/src/ejabberd.hrl index 13dd063bd..44adc0db4 100644 --- a/src/ejabberd.hrl +++ b/src/ejabberd.hrl @@ -6,6 +6,8 @@ %%% Id : $Id$ %%%---------------------------------------------------------------------- +-define(VERSION, "0.0.1-alpha"). + %-define(ejabberd_debug, true). %-define(DBGFSM, true). diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl index 0c1470900..1bae8a9fd 100644 --- a/src/ejabberd_config.erl +++ b/src/ejabberd_config.erl @@ -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 diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl index 1b970447a..f96aab3ee 100644 --- a/src/ejabberd_local.erl +++ b/src/ejabberd_local.erl @@ -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; {"", _, _} -> diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl index 8fda160c0..0ef1a93e2 100644 --- a/src/ejabberd_router.erl +++ b/src/ejabberd_router.erl @@ -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] -> diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 725c98c7c..a86dce479 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -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). + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/jlib.erl b/src/jlib.erl index 2dbd3f4d7..3cf7ed577 100644 --- a/src/jlib.erl +++ b/src/jlib.erl @@ -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]))}], []}. + diff --git a/src/mod_disco.erl b/src/mod_disco.erl index 9284e1419..aee3fc13c 100644 --- a/src/mod_disco.erl +++ b/src/mod_disco.erl @@ -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"] -> + 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_online_users() + Res }]}; - ["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) - }]}; - _ -> + {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 diff --git a/src/mod_stats.erl b/src/mod_stats.erl index 15f433b1d..3eff2621a 100644 --- a/src/mod_stats.erl +++ b/src/mod_stats.erl @@ -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 index 000000000..2820f6203 --- /dev/null +++ b/src/mod_time.erl @@ -0,0 +1,45 @@ +%%%---------------------------------------------------------------------- +%%% File : mod_time.erl +%%% Author : Alexey Shchepin +%%% Purpose : +%%% Created : 18 Jan 2003 by Alexey Shchepin +%%% 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 index 000000000..c79b5fbbe --- /dev/null +++ b/src/mod_version.erl @@ -0,0 +1,64 @@ +%%%---------------------------------------------------------------------- +%%% File : mod_version.erl +%%% Author : Alexey Shchepin +%%% Purpose : +%%% Created : 18 Jan 2003 by Alexey Shchepin +%%% 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. + + diff --git a/src/namespaces.hrl b/src/namespaces.hrl index 21835b43d..712348a91 100644 --- a/src/namespaces.hrl +++ b/src/namespaces.hrl @@ -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").