mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-20 16:15:59 +01:00
*** empty log message ***
SVN Revision: 25
This commit is contained in:
parent
201b4c602f
commit
44797c9524
@ -24,6 +24,7 @@
|
|||||||
terminate/3]).
|
terminate/3]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
|
-include("namespaces.hrl").
|
||||||
|
|
||||||
-define(SETS, gb_sets).
|
-define(SETS, gb_sets).
|
||||||
|
|
||||||
@ -288,6 +289,18 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
|
|||||||
StateData
|
StateData
|
||||||
end,
|
end,
|
||||||
{false, Attrs, NewSt};
|
{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}
|
{true, Attrs, StateData}
|
||||||
end,
|
end,
|
||||||
@ -315,6 +328,14 @@ terminate(Reason, StateName, StateData) ->
|
|||||||
ejabberd_sm:close_session(StateData#state.user,
|
ejabberd_sm:close_session(StateData#state.user,
|
||||||
StateData#state.resource)
|
StateData#state.resource)
|
||||||
end,
|
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,
|
StateData#state.sender ! close,
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
@ -463,7 +484,7 @@ presence_update(From, Packet, StateData) ->
|
|||||||
"unsubscribed" ->
|
"unsubscribed" ->
|
||||||
StateData;
|
StateData;
|
||||||
_ ->
|
_ ->
|
||||||
update_priority(jlib:get_subtag(Packet, "priority"), StateData),
|
update_priority(xml:get_subtag(Packet, "priority"), StateData),
|
||||||
FromUnavail = (StateData#state.pres_last == undefined) or
|
FromUnavail = (StateData#state.pres_last == undefined) or
|
||||||
StateData#state.pres_invis,
|
StateData#state.pres_invis,
|
||||||
?DEBUG("from unavail = ~p~n", [FromUnavail]),
|
?DEBUG("from unavail = ~p~n", [FromUnavail]),
|
||||||
|
@ -23,6 +23,7 @@ start() ->
|
|||||||
mod_register:start(),
|
mod_register:start(),
|
||||||
mod_roster:start(),
|
mod_roster:start(),
|
||||||
mod_disco:start(),
|
mod_disco:start(),
|
||||||
|
mod_vcard:start(),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
init() ->
|
init() ->
|
||||||
|
@ -10,7 +10,8 @@
|
|||||||
-author('alexey@sevcom.net').
|
-author('alexey@sevcom.net').
|
||||||
-vsn('$Revision$ ').
|
-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]).
|
-export([start/0, init/0]).
|
||||||
|
|
||||||
@ -90,7 +91,7 @@ do_route(From, To, Packet) ->
|
|||||||
[] ->
|
[] ->
|
||||||
case mnesia:read({route, DstDomain}) of
|
case mnesia:read({route, DstDomain}) of
|
||||||
[] ->
|
[] ->
|
||||||
error;
|
false;
|
||||||
[R] ->
|
[R] ->
|
||||||
{ok, R#route.node, R#route.pid}
|
{ok, R#route.node, R#route.pid}
|
||||||
end;
|
end;
|
||||||
@ -99,7 +100,7 @@ do_route(From, To, Packet) ->
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
case mnesia:transaction(F) of
|
case mnesia:transaction(F) of
|
||||||
{atomic, error} ->
|
{atomic, false} ->
|
||||||
ejabberd_s2s ! {route, From, To, Packet};
|
ejabberd_s2s ! {route, From, To, Packet};
|
||||||
{atomic, {ok, Node, Pid}} ->
|
{atomic, {ok, Node, Pid}} ->
|
||||||
case node() of
|
case node() of
|
||||||
@ -125,3 +126,9 @@ register_route(Domain) ->
|
|||||||
register_local_route(Domain) ->
|
register_local_route(Domain) ->
|
||||||
ejabberd_router ! {register_local_route, Domain, self()}.
|
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,
|
get_iq_namespace/1,
|
||||||
iq_query_info/1,
|
iq_query_info/1,
|
||||||
is_iq_request_type/1,
|
is_iq_request_type/1,
|
||||||
iq_to_xml/1,
|
iq_to_xml/1]).
|
||||||
get_subtag/2]).
|
|
||||||
|
|
||||||
|
|
||||||
%send_iq(From, To, ID, SubTags) ->
|
%send_iq(From, To, ID, SubTags) ->
|
||||||
@ -249,17 +248,3 @@ iq_to_xml({iq, ID, Type, _, SubEl}) ->
|
|||||||
end.
|
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
|
%%% File : mod_disco.erl
|
||||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||||
%%% Purpose :
|
%%% Purpose :
|
||||||
%%% Created : 1 Jan 2003 by Alexey Shchepin <alex@alex.sevcom.net>
|
%%% Created : 1 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||||
%%% Id : $Id$
|
%%% Id : $Id$
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
@ -18,9 +18,7 @@
|
|||||||
register_feature/1]).
|
register_feature/1]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
|
-include("namespaces.hrl").
|
||||||
-define(NS_DISCO_ITEMS, "http://jabber.org/protocol/disco#items").
|
|
||||||
-define(NS_DISCO_INFO, "http://jabber.org/protocol/disco#info").
|
|
||||||
|
|
||||||
-define(EMPTY_INFO_RESULT,
|
-define(EMPTY_INFO_RESULT,
|
||||||
{iq, ID, result, XMLNS, [{xmlelement, "query",
|
{iq, ID, result, XMLNS, [{xmlelement, "query",
|
||||||
@ -56,7 +54,9 @@ process_local_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
|||||||
get ->
|
get ->
|
||||||
case xml:get_tag_attr_s("node", SubEl) of
|
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,
|
{iq, ID, result, XMLNS,
|
||||||
[{xmlelement,
|
[{xmlelement,
|
||||||
"query",
|
"query",
|
||||||
@ -124,6 +124,9 @@ process_local_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
|||||||
feature_to_xml({Feature}) ->
|
feature_to_xml({Feature}) ->
|
||||||
{xmlelement, "feature", [{"var", Feature}], []}.
|
{xmlelement, "feature", [{"var", Feature}], []}.
|
||||||
|
|
||||||
|
domain_to_xml(Domain) ->
|
||||||
|
{xmlelement, "item", [{"jid", Domain}], []}.
|
||||||
|
|
||||||
|
|
||||||
get_online_users() ->
|
get_online_users() ->
|
||||||
case catch ejabberd_sm:dirty_get_sessions_list() of
|
case catch ejabberd_sm:dirty_get_sessions_list() of
|
||||||
|
@ -25,9 +25,9 @@ init() ->
|
|||||||
process_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
process_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||||
case Type of
|
case Type of
|
||||||
set ->
|
set ->
|
||||||
UTag = jlib:get_subtag(SubEl, "username"),
|
UTag = xml:get_subtag(SubEl, "username"),
|
||||||
PTag = jlib:get_subtag(SubEl, "password"),
|
PTag = xml:get_subtag(SubEl, "password"),
|
||||||
RTag = jlib:get_subtag(SubEl, "remove"),
|
RTag = xml:get_subtag(SubEl, "remove"),
|
||||||
if
|
if
|
||||||
(UTag /= false) and (RTag /= false) ->
|
(UTag /= false) and (RTag /= false) ->
|
||||||
{iq, ID, error, XMLNS,
|
{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,
|
-export([element_to_string/1, crypt/1, remove_cdata/1,
|
||||||
get_cdata/1, get_tag_cdata/1,
|
get_cdata/1, get_tag_cdata/1,
|
||||||
get_attr/2, get_attr_s/2,
|
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) ->
|
element_to_string(El) ->
|
||||||
case El of
|
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_tag_attr_s(AttrName, {xmlelement, Name, Attrs, Els}) ->
|
||||||
get_attr_s(AttrName, Attrs).
|
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