mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-22 17:28:25 +01:00
*** empty log message ***
SVN Revision: 25
This commit is contained in:
parent
201b4c602f
commit
44797c9524
@ -24,6 +24,7 @@
|
||||
terminate/3]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("namespaces.hrl").
|
||||
|
||||
-define(SETS, gb_sets).
|
||||
|
||||
@ -288,6 +289,18 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
|
||||
StateData
|
||||
end,
|
||||
{false, Attrs, NewSt};
|
||||
"iq" ->
|
||||
IQ = jlib:iq_query_info(Packet),
|
||||
case IQ of
|
||||
{iq, ID, Type, ?NS_VCARD, SubEl} ->
|
||||
ResIQ = mod_vcard:process_sm_iq(From, To, IQ),
|
||||
ejabberd_router:route(To,
|
||||
From,
|
||||
jlib:iq_to_xml(ResIQ)),
|
||||
{false, Attrs, StateData};
|
||||
_ ->
|
||||
{true, Attrs, StateData}
|
||||
end;
|
||||
_ ->
|
||||
{true, Attrs, StateData}
|
||||
end,
|
||||
@ -315,6 +328,14 @@ terminate(Reason, StateName, StateData) ->
|
||||
ejabberd_sm:close_session(StateData#state.user,
|
||||
StateData#state.resource)
|
||||
end,
|
||||
From = {StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.resource},
|
||||
Packet = {xmlelement, "presence", [{"type", "unavailable"}], []},
|
||||
ejabberd_sm:unset_presence(StateData#state.user,
|
||||
StateData#state.resource),
|
||||
presence_broadcast(From, StateData#state.pres_a, Packet),
|
||||
presence_broadcast(From, StateData#state.pres_i, Packet),
|
||||
StateData#state.sender ! close,
|
||||
ok.
|
||||
|
||||
@ -463,7 +484,7 @@ presence_update(From, Packet, StateData) ->
|
||||
"unsubscribed" ->
|
||||
StateData;
|
||||
_ ->
|
||||
update_priority(jlib:get_subtag(Packet, "priority"), StateData),
|
||||
update_priority(xml:get_subtag(Packet, "priority"), StateData),
|
||||
FromUnavail = (StateData#state.pres_last == undefined) or
|
||||
StateData#state.pres_invis,
|
||||
?DEBUG("from unavail = ~p~n", [FromUnavail]),
|
||||
|
@ -23,6 +23,7 @@ start() ->
|
||||
mod_register:start(),
|
||||
mod_roster:start(),
|
||||
mod_disco:start(),
|
||||
mod_vcard:start(),
|
||||
ok.
|
||||
|
||||
init() ->
|
||||
|
@ -10,7 +10,8 @@
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-export([route/3, register_route/1, register_local_route/1]).
|
||||
-export([route/3, register_route/1, register_local_route/1,
|
||||
dirty_get_all_routes/0]).
|
||||
|
||||
-export([start/0, init/0]).
|
||||
|
||||
@ -90,7 +91,7 @@ do_route(From, To, Packet) ->
|
||||
[] ->
|
||||
case mnesia:read({route, DstDomain}) of
|
||||
[] ->
|
||||
error;
|
||||
false;
|
||||
[R] ->
|
||||
{ok, R#route.node, R#route.pid}
|
||||
end;
|
||||
@ -99,7 +100,7 @@ do_route(From, To, Packet) ->
|
||||
end
|
||||
end,
|
||||
case mnesia:transaction(F) of
|
||||
{atomic, error} ->
|
||||
{atomic, false} ->
|
||||
ejabberd_s2s ! {route, From, To, Packet};
|
||||
{atomic, {ok, Node, Pid}} ->
|
||||
case node() of
|
||||
@ -125,3 +126,9 @@ register_route(Domain) ->
|
||||
register_local_route(Domain) ->
|
||||
ejabberd_router ! {register_local_route, Domain, self()}.
|
||||
|
||||
|
||||
dirty_get_all_routes() ->
|
||||
lists:delete(?MYNAME,
|
||||
lists:umerge(lists:sort(mnesia:dirty_all_keys(route)),
|
||||
lists:sort(mnesia:dirty_all_keys(local_route)))).
|
||||
|
||||
|
17
src/jlib.erl
17
src/jlib.erl
@ -25,8 +25,7 @@
|
||||
get_iq_namespace/1,
|
||||
iq_query_info/1,
|
||||
is_iq_request_type/1,
|
||||
iq_to_xml/1,
|
||||
get_subtag/2]).
|
||||
iq_to_xml/1]).
|
||||
|
||||
|
||||
%send_iq(From, To, ID, SubTags) ->
|
||||
@ -249,17 +248,3 @@ iq_to_xml({iq, ID, Type, _, SubEl}) ->
|
||||
end.
|
||||
|
||||
|
||||
get_subtag({xmlelement, _, _, Els}, Name) ->
|
||||
get_subtag1(Els, Name).
|
||||
|
||||
get_subtag1([El | Els], Name) ->
|
||||
case El of
|
||||
{xmlelement, Name, _, _} ->
|
||||
El;
|
||||
_ ->
|
||||
get_subtag1(Els, Name)
|
||||
end;
|
||||
get_subtag1([], _) ->
|
||||
false.
|
||||
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
%%% File : mod_disco.erl
|
||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Purpose :
|
||||
%%% Created : 1 Jan 2003 by Alexey Shchepin <alex@alex.sevcom.net>
|
||||
%%% Created : 1 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@ -18,9 +18,7 @@
|
||||
register_feature/1]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
-define(NS_DISCO_ITEMS, "http://jabber.org/protocol/disco#items").
|
||||
-define(NS_DISCO_INFO, "http://jabber.org/protocol/disco#info").
|
||||
-include("namespaces.hrl").
|
||||
|
||||
-define(EMPTY_INFO_RESULT,
|
||||
{iq, ID, result, XMLNS, [{xmlelement, "query",
|
||||
@ -56,7 +54,9 @@ process_local_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
get ->
|
||||
case xml:get_tag_attr_s("node", SubEl) of
|
||||
"" ->
|
||||
Domains = [],
|
||||
Domains =
|
||||
lists:map(fun domain_to_xml/1,
|
||||
ejabberd_router:dirty_get_all_routes()),
|
||||
{iq, ID, result, XMLNS,
|
||||
[{xmlelement,
|
||||
"query",
|
||||
@ -124,6 +124,9 @@ process_local_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
feature_to_xml({Feature}) ->
|
||||
{xmlelement, "feature", [{"var", Feature}], []}.
|
||||
|
||||
domain_to_xml(Domain) ->
|
||||
{xmlelement, "item", [{"jid", Domain}], []}.
|
||||
|
||||
|
||||
get_online_users() ->
|
||||
case catch ejabberd_sm:dirty_get_sessions_list() of
|
||||
|
@ -25,9 +25,9 @@ init() ->
|
||||
process_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
case Type of
|
||||
set ->
|
||||
UTag = jlib:get_subtag(SubEl, "username"),
|
||||
PTag = jlib:get_subtag(SubEl, "password"),
|
||||
RTag = jlib:get_subtag(SubEl, "remove"),
|
||||
UTag = xml:get_subtag(SubEl, "username"),
|
||||
PTag = xml:get_subtag(SubEl, "password"),
|
||||
RTag = xml:get_subtag(SubEl, "remove"),
|
||||
if
|
||||
(UTag /= false) and (RTag /= false) ->
|
||||
{iq, ID, error, XMLNS,
|
||||
|
239
src/mod_vcard.erl
Normal file
239
src/mod_vcard.erl
Normal file
@ -0,0 +1,239 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : mod_vcard.erl
|
||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Purpose :
|
||||
%%% Created : 2 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(mod_vcard).
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-export([start/0, init/0,
|
||||
process_local_iq/3,
|
||||
process_sm_iq/3]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("namespaces.hrl").
|
||||
|
||||
|
||||
-record(vcard_search, {user, fn, family, given, middle, nickname,
|
||||
bday, ctry, locality, email,
|
||||
orgname, orgunit}).
|
||||
-record(vcard, {user, vcard}).
|
||||
|
||||
|
||||
start() ->
|
||||
mnesia:create_table(vcard, [{disc_only_copies, [node()]},
|
||||
{attributes, record_info(fields, vcard)}]),
|
||||
mnesia:create_table(vcard_search,
|
||||
[{disc_copies, [node()]},
|
||||
{attributes, record_info(fields, vcard_search)}]),
|
||||
%mnesia:add_table_index(vcard_search, fn),
|
||||
%mnesia:add_table_index(vcard_search, n),
|
||||
%mnesia:add_table_index(vcard_search, nickname),
|
||||
%mnesia:add_table_index(vcard_search, bday),
|
||||
%mnesia:add_table_index(vcard_search, ctry),
|
||||
%mnesia:add_table_index(vcard_search, locality),
|
||||
%mnesia:add_table_index(vcard_search, email),
|
||||
%mnesia:add_table_index(vcard_search, orgname),
|
||||
%mnesia:add_table_index(vcard_search, orgunit),
|
||||
|
||||
|
||||
ejabberd_local:register_iq_handler(?NS_VCARD,
|
||||
?MODULE, process_local_iq),
|
||||
ejabberd_sm:register_iq_handler(?NS_VCARD,
|
||||
?MODULE, process_sm_iq),
|
||||
spawn(?MODULE, init, []).
|
||||
|
||||
init() ->
|
||||
ejabberd_router:register_local_route("ejud." ++ ?MYNAME),
|
||||
loop().
|
||||
|
||||
loop() ->
|
||||
receive
|
||||
{route, From, To, Packet} ->
|
||||
do_route(From, To, Packet),
|
||||
loop();
|
||||
_ ->
|
||||
loop()
|
||||
end.
|
||||
|
||||
|
||||
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
case Type of
|
||||
set ->
|
||||
{User, Server, _} = From,
|
||||
LUser = jlib:tolower(User),
|
||||
LServer = jlib:tolower(Server),
|
||||
case ?MYNAME of
|
||||
LServer ->
|
||||
set_vcard(LUser, SubEl),
|
||||
{iq, ID, result, XMLNS, []};
|
||||
_ ->
|
||||
{iq, ID, error, XMLNS,
|
||||
[SubEl, {xmlelement, "error",
|
||||
[{"code", "405"}],
|
||||
[{xmlcdata, "Not Allowed"}]}]}
|
||||
end;
|
||||
get ->
|
||||
{iq, ID, result, XMLNS,
|
||||
[{xmlelement, "vCard",
|
||||
[{"xmlns", ?NS_VCARD}],
|
||||
[{xmlelement, "FN", [],
|
||||
[{xmlcdata, "ejabberd"}]},
|
||||
{xmlelement, "URL", [],
|
||||
[{xmlcdata,
|
||||
"http://www.jabber.ru/projects/ejabberd/"}]},
|
||||
{xmlelement, "DESC", [],
|
||||
[{xmlcdata, "Erlang Jabber Server\n"
|
||||
"Copyright (c) 2002, 2003 Alexey Shchepin"}]},
|
||||
{xmlelement, "BDAY", [],
|
||||
[{xmlcdata, "20021116"}]}
|
||||
]}]}
|
||||
end.
|
||||
|
||||
|
||||
process_sm_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 ->
|
||||
{User, _, _} = To,
|
||||
LUser = jlib:tolower(User),
|
||||
F = fun() ->
|
||||
mnesia:read({vcard, LUser})
|
||||
end,
|
||||
Els = case mnesia:transaction(F) of
|
||||
{atomic, Rs} ->
|
||||
lists:map(fun(R) ->
|
||||
R#vcard.vcard
|
||||
end, Rs);
|
||||
{aborted, Reason} ->
|
||||
[]
|
||||
end,
|
||||
{iq, ID, result, XMLNS, Els}
|
||||
end.
|
||||
|
||||
|
||||
set_vcard(LUser, VCARD) ->
|
||||
FN = xml:get_path_s(VCARD, [{elem, "FN"}, cdata]),
|
||||
Family = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "FAMILY"}, cdata]),
|
||||
Given = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "GIVEN"}, cdata]),
|
||||
Middle = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "MIDDLE"}, cdata]),
|
||||
Nickname = xml:get_path_s(VCARD, [{elem, "NICKNAME"}, cdata]),
|
||||
BDay = xml:get_path_s(VCARD, [{elem, "BDAY"}, cdata]),
|
||||
%ctry = xml:get_path_s(VCARD, [{elem, "CTRY"}, cdata]),
|
||||
%locality = xml:get_path_s(VCARD, [{elem, "FN"}, cdata]),
|
||||
EMail = xml:get_path_s(VCARD, [{elem, "EMAIL"}, cdata]),
|
||||
OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]),
|
||||
OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]),
|
||||
F = fun() ->
|
||||
mnesia:write(#vcard{user = LUser, vcard = VCARD}),
|
||||
mnesia:write(#vcard_search{user = LUser,
|
||||
fn = FN,
|
||||
family = Family,
|
||||
given = Given,
|
||||
middle = Middle,
|
||||
nickname = Nickname,
|
||||
bday = BDay,
|
||||
%ctry = CTRY,
|
||||
%locality = Locality,
|
||||
email = EMail,
|
||||
orgname = OrgName,
|
||||
orgunit = OrgUnit
|
||||
})
|
||||
end,
|
||||
mnesia:transaction(F).
|
||||
|
||||
-define(FORM,
|
||||
[{xmlelement, "instructions", [],
|
||||
[{xmlcdata, "You need a x:data capable client to search"}]},
|
||||
{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}],
|
||||
[{xmlelement, "title", [], [{xmlcdata, "Users Search"}]},
|
||||
{xmlelement, "instructions", [],
|
||||
[{xmlcdata, "Fill in fields to search "
|
||||
"for any matching Jabber User"}]},
|
||||
{xmlelement, "field", [{"type", "text-single"},
|
||||
{"label", "Full Name"},
|
||||
{"var", "fn"}], []}
|
||||
]}]).
|
||||
|
||||
|
||||
|
||||
|
||||
do_route(From, To, Packet) ->
|
||||
{User, Server, Resource} = To,
|
||||
if
|
||||
(User /= "") or (Resource /= "") ->
|
||||
Err = jlib:make_error_reply(Packet, "503", "Service Unavailable"),
|
||||
ejabberd_router ! {route, To, From, Err};
|
||||
true ->
|
||||
IQ = jlib:iq_query_info(Packet),
|
||||
case IQ of
|
||||
{iq, ID, Type, ?NS_SEARCH, SubEl} ->
|
||||
case Type of
|
||||
set ->
|
||||
% TODO
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, "501", "Not Implemented"),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
get ->
|
||||
ResIQ = {iq, ID, result, ?NS_SEARCH,
|
||||
[{xmlelement,
|
||||
"query",
|
||||
[{"xmlns", ?NS_SEARCH}],
|
||||
?FORM
|
||||
}]},
|
||||
ejabberd_router:route(To,
|
||||
From,
|
||||
jlib:iq_to_xml(ResIQ))
|
||||
end;
|
||||
{iq, ID, Type, ?NS_DISCO_INFO, SubEl} ->
|
||||
case Type of
|
||||
set ->
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, "405", "Not Allowed"),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
get ->
|
||||
ResIQ = {iq, ID, result, ?NS_DISCO_INFO,
|
||||
[{xmlelement,
|
||||
"query",
|
||||
[{"xmlns", ?NS_DISCO_INFO}],
|
||||
[{xmlelement, "identity",
|
||||
[{"category", "directory"},
|
||||
{"type", "user"},
|
||||
{"name", "EJUD"}], []},
|
||||
{xmlelement, "feature",
|
||||
[{"var", ?NS_SEARCH}], []}
|
||||
]
|
||||
}]},
|
||||
ejabberd_router:route(To,
|
||||
From,
|
||||
jlib:iq_to_xml(ResIQ))
|
||||
end;
|
||||
{iq, ID, Type, ?NS_DISCO_ITEMS, SubEl} ->
|
||||
case Type of
|
||||
set ->
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, "405", "Not Allowed"),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
get ->
|
||||
ResIQ = {iq, ID, result, ?NS_DISCO_INFO,
|
||||
[{xmlelement,
|
||||
"query",
|
||||
[{"xmlns", ?NS_DISCO_INFO}], []}]},
|
||||
ejabberd_router:route(To,
|
||||
From,
|
||||
jlib:iq_to_xml(ResIQ))
|
||||
end;
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
"503", "Service Unavailable"),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end
|
||||
end.
|
||||
|
14
src/namespaces.hrl
Normal file
14
src/namespaces.hrl
Normal file
@ -0,0 +1,14 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : namespaces.hrl
|
||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Purpose :
|
||||
%%% Created : 2 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-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_SEARCH, "jabber:iq:search").
|
||||
-define(NS_XDATA, "jabber:x:data").
|
||||
|
||||
|
33
src/xml.erl
33
src/xml.erl
@ -13,7 +13,9 @@
|
||||
-export([element_to_string/1, crypt/1, remove_cdata/1,
|
||||
get_cdata/1, get_tag_cdata/1,
|
||||
get_attr/2, get_attr_s/2,
|
||||
get_tag_attr/2, get_tag_attr_s/2]).
|
||||
get_tag_attr/2, get_tag_attr_s/2,
|
||||
get_subtag/2,
|
||||
get_path_s/2]).
|
||||
|
||||
element_to_string(El) ->
|
||||
case El of
|
||||
@ -100,3 +102,32 @@ get_tag_attr(AttrName, {xmlelement, Name, Attrs, Els}) ->
|
||||
get_tag_attr_s(AttrName, {xmlelement, Name, Attrs, Els}) ->
|
||||
get_attr_s(AttrName, Attrs).
|
||||
|
||||
|
||||
get_subtag({xmlelement, _, _, Els}, Name) ->
|
||||
get_subtag1(Els, Name).
|
||||
|
||||
get_subtag1([El | Els], Name) ->
|
||||
case El of
|
||||
{xmlelement, Name, _, _} ->
|
||||
El;
|
||||
_ ->
|
||||
get_subtag1(Els, Name)
|
||||
end;
|
||||
get_subtag1([], _) ->
|
||||
false.
|
||||
|
||||
|
||||
get_path_s(El, []) ->
|
||||
El;
|
||||
get_path_s(El, [{elem, Name} | Path]) ->
|
||||
case get_subtag(El, Name) of
|
||||
false ->
|
||||
"";
|
||||
SubEl ->
|
||||
get_path_s(SubEl, Path)
|
||||
end;
|
||||
get_path_s(El, [{attr, Name}]) ->
|
||||
get_tag_attr_s(Name, El);
|
||||
get_path_s(El, [cdata]) ->
|
||||
get_tag_cdata(El).
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user