*** empty log message ***

SVN Revision: 25
This commit is contained in:
Alexey Shchepin 2003-01-02 21:01:12 +00:00
parent 201b4c602f
commit 44797c9524
9 changed files with 330 additions and 29 deletions

View File

@ -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]),

View File

@ -23,6 +23,7 @@ start() ->
mod_register:start(),
mod_roster:start(),
mod_disco:start(),
mod_vcard:start(),
ok.
init() ->

View File

@ -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)))).

View File

@ -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.

View File

@ -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

View File

@ -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
View 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
View 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").

View File

@ -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).