*** empty log message ***

SVN Revision: 29
This commit is contained in:
Alexey Shchepin 2003-01-05 20:24:59 +00:00
parent 083e2b75d0
commit 0a9a6261f8
11 changed files with 256 additions and 111 deletions

View File

@ -20,11 +20,12 @@
set_password/2,
check_password/2,
check_password/4,
try_register/2]).
try_register/2,
dirty_get_registered_users/0,
is_user_exists/1]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
dirty_get_registered_users/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2]).
-record(state, {}).
@ -162,3 +163,19 @@ try_register(User, Password) ->
dirty_get_registered_users() ->
mnesia:dirty_all_keys(passwd).
is_user_exists(User) ->
LUser = jlib:tolower(User),
F = fun() ->
case mnesia:read({passwd, LUser}) of
[] ->
false;
[_] ->
true
end
end,
case mnesia:transaction(F) of
{atomic, Res} ->
Res;
_ ->
false
end.

View File

@ -492,7 +492,9 @@ presence_update(From, Packet, StateData) ->
if
FromUnavail ->
% TODO: watching ourself
mod_offline:resend_offline_messages(
StateData#state.user),
presence_broadcast_first(From, StateData, Packet);
true ->
presence_broadcast_to_trusted(From,

View File

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

View File

@ -18,8 +18,8 @@
-include_lib("mnemosyne/include/mnemosyne.hrl").
-include("ejabberd.hrl").
-record(s2s, {server, node, key}).
-record(mys2s, {server, pid}).
-record(s2s, {fromto, node, key}).
-record(mys2s, {fromto, pid}).
start() ->
@ -43,8 +43,8 @@ loop() ->
% replace_and_register_my_connection(User, Resource, From),
% replace_alien_connection(User, Resource),
% loop();
{closed_conection, Server} ->
remove_connection(Server),
{closed_conection, FromTo} ->
remove_connection(FromTo),
loop();
%{replace, User, Resource} ->
% replace_my_connection(User, Resource),
@ -67,10 +67,10 @@ loop() ->
% ejabberd_s2s ! {close_session, User, Resource}.
remove_connection(Server) ->
remove_connection(FromTo) ->
F = fun() ->
mnesia:delete({mys2s, Server}),
mnesia:delete({s2s, Server})
mnesia:delete({mys2s, FromTo}),
mnesia:delete({s2s, FromTo})
end,
mnesia:transaction(F).
@ -85,9 +85,9 @@ clean_table_from_bad_node(Node) ->
end,
mnesia:transaction(F).
have_connection(Server) ->
have_connection(FromTo) ->
F = fun() ->
[E] = mnesia:read({s2s, Server})
[E] = mnesia:read({s2s, FromTo})
end,
case mnesia:transaction(F) of
{atomic, _} ->
@ -96,9 +96,9 @@ have_connection(Server) ->
false
end.
get_key(Server) ->
get_key(FromTo) ->
F = fun() ->
[E] = mnesia:read({s2s, Server}),
[E] = mnesia:read({s2s, FromTo}),
E
end,
case mnesia:transaction(F) of
@ -108,15 +108,15 @@ get_key(Server) ->
""
end.
try_register(Server) ->
try_register(FromTo) ->
Key = randoms:get_string(),
F = fun() ->
case mnesia:read({s2s, Server}) of
case mnesia:read({s2s, FromTo}) of
[] ->
mnesia:write(#s2s{server = Server,
mnesia:write(#s2s{fromto = FromTo,
node = node(),
key = Key}),
mnesia:write(#mys2s{server = Server,
mnesia:write(#mys2s{fromto = FromTo,
pid = self()}),
{key, Key};
_ ->
@ -139,16 +139,17 @@ do_route(From, To, Packet) ->
[From, To, Packet, 8]),
{_, MyServer, _} = From,
{User, Server, Resource} = To,
FromTo = {MyServer, Server},
Key = randoms:get_string(),
F = fun() ->
case mnesia:read({mys2s, Server}) of
case mnesia:read({mys2s, FromTo}) of
[] ->
case mnesia:read({s2s, Server}) of
case mnesia:read({s2s, FromTo}) of
[Er] ->
{remote, Er#s2s.node};
[] ->
% TODO
mnesia:write(#s2s{server = Server,
mnesia:write(#s2s{fromto = FromTo,
node = node(),
key = Key}),
new
@ -174,7 +175,7 @@ do_route(From, To, Packet) ->
{atomic, new} ->
?DEBUG("starting new s2s connection~n", []),
Pid = ejabberd_s2s_out:start(MyServer, Server, {new, Key}),
mnesia:transaction(fun() -> mnesia:write(#mys2s{server = Server,
mnesia:transaction(fun() -> mnesia:write(#mys2s{fromto = FromTo,
pid = Pid}) end),
{xmlelement, Name, Attrs, Els} = Packet,
NewAttrs = jlib:replace_from_to_attrs(jlib:jid_to_string(From),

View File

@ -129,7 +129,7 @@ wait_for_key({xmlstreamelement, El}, StateData) ->
StateData#state{server = From}};
{verify, To, From, Id, Key} ->
io:format("VERIFY KEY: ~p~n", [{To, From, Id, Key}]),
Key1 = ejabberd_s2s:get_key(From),
Key1 = ejabberd_s2s:get_key({StateData#state.myname, From}),
Type = if Key == Key1 -> "valid";
true -> "invalid"
end,
@ -178,7 +178,7 @@ wait_for_verification({xmlstreamelement, El}, StateData) ->
case is_key_packet(El) of
{verify, To, From, Id, Key} ->
io:format("VERIFY KEY: ~p~n", [{To, From, Id, Key}]),
Key1 = ejabberd_s2s:get_key(From),
Key1 = ejabberd_s2s:get_key({StateData#state.myname, From}),
Type = if Key == Key1 -> "valid";
true -> "invalid"
end,
@ -209,7 +209,8 @@ stream_established({xmlstreamelement, El}, StateData) ->
case is_key_packet(El) of
{verify, To, From, Id, Key} ->
io:format("VERIFY KEY: ~p~n", [{To, From, Id, Key}]),
Key1 = ejabberd_s2s:get_key(From),
Key1 = ejabberd_s2s:get_key({StateData#state.myname,
From}),
Type = if Key == Key1 -> "valid";
true -> "invalid"
end,

View File

@ -122,7 +122,9 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) ->
Server = StateData#state.server,
New = case StateData#state.new of
false ->
case ejabberd_s2s:try_register(Server) of
case
ejabberd_s2s:try_register(
{StateData#state.myname, Server}) of
{key, Key} ->
Key;
false ->
@ -331,7 +333,8 @@ terminate(Reason, StateName, StateData) ->
false ->
ok;
Key ->
ejabberd_s2s ! {closed_conection, StateData#state.server}
ejabberd_s2s ! {closed_conection, {StateData#state.myname,
StateData#state.server}}
end,
case StateData#state.socket of
undefined ->

View File

@ -23,7 +23,6 @@
-record(session, {ur, user, node}).
-record(mysession, {ur, pid}).
-record(presence, {ur, user, priority}).
-record(offline_msg, {user, timestamp, xml}).
start() ->
spawn(ejabberd_sm, init, []).
@ -226,20 +225,9 @@ do_route(From, To, Packet) ->
ok
end;
"message" ->
case catch lists:max(get_user_present_resources(User)) of
{'EXIT', _} ->
% TODO
ok;
{_, R} ->
ejabberd_sm ! {route,
From,
{User, Server, R},
Packet}
end;
route_message(From, To, Packet);
"iq" ->
process_iq(From, To, Packet),
% TODO
ok;
process_iq(From, To, Packet);
"broadcast" ->
lists:foreach(
fun(R) ->
@ -262,8 +250,12 @@ do_route(From, To, Packet) ->
{ejabberd_sm, Node} ! {route, From, To, Packet},
ok;
{atomic, not_exists} ->
% TODO
?DEBUG("packet droped~n", []),
if
Name == "message" ->
route_message(From, To, Packet);
true ->
?DEBUG("packet droped~n", [])
end,
ok;
{aborted, Reason} ->
?DEBUG("delivery failed: ~p~n", [Reason]),
@ -271,6 +263,24 @@ do_route(From, To, Packet) ->
end
end.
route_message(From, To, Packet) ->
{User, Server, Resource} = To,
case catch lists:max(get_user_present_resources(User)) of
{'EXIT', _} ->
case ejabberd_auth:is_user_exists(User) of
true ->
mod_offline:store_packet(From, To, Packet);
_ ->
?DEBUG("packet droped~n", [])
end;
{_, R} ->
ejabberd_sm ! {route,
From,
{User, Server, R},
Packet}
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
get_user_resources(User) ->

View File

@ -26,8 +26,10 @@
iq_query_info/1,
is_iq_request_type/1,
iq_to_xml/1,
parse_xdata_submit/1]).
parse_xdata_submit/1,
timestamp_to_xml/1]).
-include("namespaces.hrl").
%send_iq(From, To, ID, SubTags) ->
% ok.
@ -289,3 +291,12 @@ parse_xdata_values([{xmlelement, Name, Attrs, SubEls} | Els], Res) ->
end;
parse_xdata_values([_ | Els], Res) ->
parse_xdata_values(Els, Res).
timestamp_to_xml({{Year, Month, Day}, {Hour, Minute, Second}}) ->
{xmlelement, "x",
[{"xmlns", ?NS_DELAY},
{"stamp", lists:flatten(
io_lib:format("~4..0w~2..0w~2..0wT~2..0w:~2..0w:~2..0w",
[Year, Month, Day, Hour, Minute, Second]))}],
[]}.

112
src/mod_offline.erl Normal file
View File

@ -0,0 +1,112 @@
%%%----------------------------------------------------------------------
%%% File : mod_offline.erl
%%% Author : Alexey Shchepin <alexey@sevcom.net>
%%% Purpose :
%%% Created : 5 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
%%%----------------------------------------------------------------------
-module(mod_offline).
-author('alexey@sevcom.net').
-export([start/0,
store_packet/3,
resend_offline_messages/1]).
-include("namespaces.hrl").
-record(offline_msg, {user, timestamp, from, to, packet}).
start() ->
mnesia:create_table(offline_msg,
[{disc_only_copies, [node()]},
{type, bag},
{attributes, record_info(fields, offline_msg)}]).
store_packet(From, To, Packet) ->
case check_event(From, To, Packet) of
true ->
{User, Server, Resource} = To,
LUser = jlib:tolower(User),
TimeStamp = calendar:universal_time(),
F = fun() ->
mnesia:write(#offline_msg{user = LUser,
timestamp = TimeStamp,
from = From,
to = To,
packet = Packet})
end,
mnesia:transaction(F);
_ ->
ok
end.
check_event(From, To, Packet) ->
{xmlelement, Name, Attrs, Els} = Packet,
case find_x_event(Els) of
false ->
true;
El ->
case xml:get_subtag(El, "id") of
false ->
case xml:get_subtag(El, "offline") of
false ->
true;
_ ->
ID = case xml:get_tag_attr_s("id", Packet) of
"" ->
{xmlelement, "id", [], []};
S ->
{xmlelement, "id", [],
[{xmlcdata, S}]}
end,
ejabberd_router:route(
To, From, {xmlelement, Name, Attrs,
[{xmlelement, "x",
[{"xmlns", ?NS_EVENT}],
[ID,
{xmlelement, "offline", [], []}]}]
}),
true
end;
_ ->
false
end
end.
find_x_event([]) ->
false;
find_x_event([El | Els]) ->
case xml:get_tag_attr_s("xmlns", El) of
?NS_EVENT ->
El;
_ ->
find_x_event(Els)
end.
resend_offline_messages(User) ->
LUser = jlib:tolower(User),
F = fun() ->
Rs = mnesia:read({offline_msg, LUser}),
mnesia:delete({offline_msg, LUser}),
Rs
end,
case mnesia:transaction(F) of
{atomic, Rs} ->
lists:foreach(
fun(R) ->
{xmlelement, Name, Attrs, Els} = R#offline_msg.packet,
ejabberd_sm !
{route,
R#offline_msg.from,
R#offline_msg.to,
{xmlelement, Name, Attrs,
Els ++
[jlib:timestamp_to_xml(R#offline_msg.timestamp)]}}
end,
lists:keysort(#offline_msg.timestamp, Rs));
_ ->
ok
end.

View File

@ -128,8 +128,8 @@ set_vcard(LUser, VCARD) ->
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]),
CTRY = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "CTRY"}, cdata]),
Locality = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "LOCALITY"},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]),
@ -140,6 +140,8 @@ set_vcard(LUser, VCARD) ->
LMiddle = jlib:tolower(Middle),
LNickname = jlib:tolower(Nickname),
LBDay = jlib:tolower(BDay),
LCTRY = jlib:tolower(CTRY),
LLocality = jlib:tolower(Locality),
LEMail = jlib:tolower(EMail),
LOrgName = jlib:tolower(OrgName),
LOrgUnit = jlib:tolower(OrgUnit),
@ -153,8 +155,8 @@ set_vcard(LUser, VCARD) ->
middle = LMiddle,
nickname = LNickname,
bday = LBDay,
%ctry = LCTRY,
%locality = LLocality,
ctry = LCTRY,
locality = LLocality,
email = LEMail,
orgname = LOrgName,
orgunit = LOrgUnit
@ -162,6 +164,11 @@ set_vcard(LUser, VCARD) ->
end,
mnesia:transaction(F).
-define(TLFIELD(Type, Label, Var),
{xmlelement, "field", [{"type", Type},
{"label", Label},
{"var", Var}], []}).
-define(FORM,
[{xmlelement, "instructions", [],
@ -171,42 +178,18 @@ set_vcard(LUser, VCARD) ->
{xmlelement, "instructions", [],
[{xmlcdata, "Fill in fields to search "
"for any matching Jabber User"}]},
{xmlelement, "field", [{"type", "text-single"},
{"label", "User"},
{"var", "user"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "Full Name"},
{"var", "fn"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "Name"},
{"var", "given"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "Middle Name"},
{"var", "middle"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "Family Name"},
{"var", "family"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "Nickname"},
{"var", "nickname"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "Birthday"},
{"var", "bday"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "Country"},
{"var", "ctry"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "City"},
{"var", "locality"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "email"},
{"var", "email"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "Organization Name"},
{"var", "orgname"}], []},
{xmlelement, "field", [{"type", "text-single"},
{"label", "Organization Unit"},
{"var", "orgunit"}], []}
?TLFIELD("text-single", "User", "user"),
?TLFIELD("text-single", "Full Name", "fn"),
?TLFIELD("text-single", "Name", "given"),
?TLFIELD("text-single", "Middle Name", "middle"),
?TLFIELD("text-single", "Family Name", "family"),
?TLFIELD("text-single", "Nickname", "nickname"),
?TLFIELD("text-single", "Birthday", "bday"),
?TLFIELD("text-single", "Country", "ctry"),
?TLFIELD("text-single", "City", "locality"),
?TLFIELD("text-single", "email", "email"),
?TLFIELD("text-single", "Organization Name", "orgname"),
?TLFIELD("text-single", "Organization Unit", "orgunit")
]}]).
@ -325,23 +308,24 @@ find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) ->
find_xdata_el1([_ | Els]) ->
find_xdata_el1(Els).
-define(LFIELD(Label, Var),
{xmlelement, "field", [{"label", Label}, {"var", Var}], []}).
search_result(Data) ->
[{xmlelement, "title", [], [{xmlcdata, "Users Search Results"}]},
{xmlelement, "reported", [],
[{xmlelement, "field", [{"label", "JID"}, {"var", "jid"}], []},
{xmlelement, "field", [{"label", "Full Name"}, {"var", "fn"}], []},
{xmlelement, "field", [{"label", "Name"}, {"var", "given"}], []},
{xmlelement, "field", [{"label", "Middle Name"}, {"var", "middle"}], []},
{xmlelement, "field", [{"label", "Family Name"}, {"var", "family"}], []},
{xmlelement, "field", [{"label", "Nickname"}, {"var", "nickname"}], []},
{xmlelement, "field", [{"label", "Birthday"}, {"var", "bday"}], []},
{xmlelement, "field", [{"label", "Country"}, {"var", "ctry"}], []},
{xmlelement, "field", [{"label", "City"}, {"var", "locality"}], []},
{xmlelement, "field", [{"label", "email"}, {"var", "email"}], []},
{xmlelement, "field", [{"label", "Organization Name"},
{"var", "orgname"}], []},
{xmlelement, "field", [{"label", "Organization Unit"},
{"var", "orgunit"}], []}
[?LFIELD("JID", "jid"),
?LFIELD("Full Name", "fn"),
?LFIELD("Name", "given"),
?LFIELD("Middle Name", "middle"),
?LFIELD("Family Name", "family"),
?LFIELD("Nickname", "nickname"),
?LFIELD("Birthday", "bday"),
?LFIELD("Country", "ctry"),
?LFIELD("City", "locality"),
?LFIELD("email", "email"),
?LFIELD("Organization Name", "orgname"),
?LFIELD("Organization Unit", "orgunit")
]}] ++ lists:map(fun record_to_item/1, search(Data)).
-define(FIELD(Var, Val),
@ -402,19 +386,20 @@ filter_fields([], Match) ->
Match;
filter_fields([{SVar, [Val]} | Ds], Match)
when is_list(Val) and (Val /= "") ->
LVal = jlib:tolower(Val),
NewMatch = case SVar of
"user" -> Match#vcard_search{user = Val};
"fn" -> Match#vcard_search{fn = Val};
"family" -> Match#vcard_search{family = Val};
"given" -> Match#vcard_search{given = Val};
"middle" -> Match#vcard_search{middle = Val};
"nickname" -> Match#vcard_search{nickname = Val};
"bday" -> Match#vcard_search{bday = Val};
"ctry" -> Match#vcard_search{ctry = Val};
"locality" -> Match#vcard_search{locality = Val};
"email" -> Match#vcard_search{email = Val};
"orgname" -> Match#vcard_search{orgname = Val};
"orgunit" -> Match#vcard_search{orgunit = Val};
"user" -> Match#vcard_search{user = LVal};
"fn" -> Match#vcard_search{fn = LVal};
"family" -> Match#vcard_search{family = LVal};
"given" -> Match#vcard_search{given = LVal};
"middle" -> Match#vcard_search{middle = LVal};
"nickname" -> Match#vcard_search{nickname = LVal};
"bday" -> Match#vcard_search{bday = LVal};
"ctry" -> Match#vcard_search{ctry = LVal};
"locality" -> Match#vcard_search{locality = LVal};
"email" -> Match#vcard_search{email = LVal};
"orgname" -> Match#vcard_search{orgname = LVal};
"orgunit" -> Match#vcard_search{orgunit = LVal};
_ -> Match
end,
filter_fields(Ds, NewMatch);

View File

@ -10,5 +10,7 @@
-define(NS_VCARD, "vcard-temp").
-define(NS_SEARCH, "jabber:iq:search").
-define(NS_XDATA, "jabber:x:data").
-define(NS_DELAY, "jabber:x:delay").
-define(NS_EVENT, "jabber:x:event").