mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
* (all): Changed JID storage format, added support for stringprep
* src/stringprep/: Added support for Unicode normalization form KC * src/stringprep/: Added support for case convertion to multiple characters * src/cyrsasl_digest.erl: Temporary removed "auth-int" QOP SVN Revision: 144
This commit is contained in:
parent
e1de741cfc
commit
61875f80b3
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
||||
2003-10-07 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
* (all): Changed JID storage format, added support for stringprep
|
||||
|
||||
* src/stringprep/: Added support for Unicode normalization form KC
|
||||
|
||||
2003-10-05 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
* src/stringprep/: Added support for case convertion to multiple
|
||||
characters
|
||||
|
||||
* src/cyrsasl_digest.erl: Temporary removed "auth-int" QOP
|
||||
|
||||
2003-09-28 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
* src/stringprep/stringprep_drv.c: Added support for nameprep,
|
||||
|
@ -49,7 +49,7 @@ check_authzid(State, Props) ->
|
||||
error ->
|
||||
{error, "invalid-authzid"};
|
||||
JID ->
|
||||
LUser = xml:get_attr_s(username, Props),
|
||||
LUser = jlib:nodeprep(xml:get_attr_s(username, Props)),
|
||||
{U, S, R} = jlib:jid_tolower(JID),
|
||||
case R of
|
||||
"" ->
|
||||
|
@ -34,7 +34,8 @@ mech_new() ->
|
||||
mech_step(#state{step = 1, nonce = Nonce} = State, "") ->
|
||||
{continue,
|
||||
"nonce=\"" ++ jlib:encode_base64(Nonce) ++
|
||||
"\",qop=\"auth,auth-int\",charset=utf-8,algorithm=md5-sess",
|
||||
"\",qop=\"auth\",charset=utf-8,algorithm=md5-sess",
|
||||
%"\",qop=\"auth,auth-int\",charset=utf-8,algorithm=md5-sess",
|
||||
State#state{step = 3}};
|
||||
mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
|
||||
case parse(ClientIn) of
|
||||
|
@ -109,7 +109,7 @@ terminate(Reason, State) ->
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
check_password(User, Password) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
case catch mnesia:dirty_read({passwd, LUser}) of
|
||||
[#passwd{password = Password}] ->
|
||||
true;
|
||||
@ -118,7 +118,7 @@ check_password(User, Password) ->
|
||||
end.
|
||||
|
||||
check_password(User, Password, StreamID, Digest) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
F = fun() ->
|
||||
case mnesia:read({passwd, LUser}) of
|
||||
[E] ->
|
||||
@ -144,14 +144,14 @@ check_password(User, Password, StreamID, Digest) ->
|
||||
|
||||
|
||||
set_password(User, Password) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
F = fun() ->
|
||||
mnesia:write(#passwd{user = LUser, password = Password})
|
||||
end,
|
||||
mnesia:transaction(F).
|
||||
|
||||
try_register(User, Password) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
F = fun() ->
|
||||
case mnesia:read({passwd, LUser}) of
|
||||
[] ->
|
||||
@ -168,7 +168,7 @@ dirty_get_registered_users() ->
|
||||
mnesia:dirty_all_keys(passwd).
|
||||
|
||||
get_password(User) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
case catch mnesia:dirty_read(passwd, LUser) of
|
||||
[#passwd{password = Password}] ->
|
||||
Password;
|
||||
@ -177,7 +177,7 @@ get_password(User) ->
|
||||
end.
|
||||
|
||||
get_password_s(User) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
case catch mnesia:dirty_read(passwd, LUser) of
|
||||
[#passwd{password = Password}] ->
|
||||
Password;
|
||||
@ -186,7 +186,7 @@ get_password_s(User) ->
|
||||
end.
|
||||
|
||||
is_user_exists(User) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
case catch mnesia:dirty_read({passwd, LUser}) of
|
||||
[] ->
|
||||
false;
|
||||
@ -197,14 +197,14 @@ is_user_exists(User) ->
|
||||
end.
|
||||
|
||||
remove_user(User) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
F = fun() ->
|
||||
mnesia:delete({passwd, LUser})
|
||||
end,
|
||||
mnesia:transaction(F).
|
||||
|
||||
remove_user(User, Password) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
F = fun() ->
|
||||
case mnesia:read({passwd, LUser}) of
|
||||
[#passwd{password = Password}] ->
|
||||
|
@ -45,6 +45,7 @@
|
||||
access,
|
||||
shaper,
|
||||
authentificated = false,
|
||||
jid,
|
||||
user = "", server = ?MYNAME, resource = "",
|
||||
pres_t = ?SETS:new(),
|
||||
pres_f = ?SETS:new(),
|
||||
@ -205,7 +206,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
{next_state, wait_for_auth, StateData};
|
||||
{auth, ID, set, {U, P, D, R}} ->
|
||||
io:format("AUTH: ~p~n", [{U, P, D, R}]),
|
||||
JID = {U, ?MYNAME, R},
|
||||
JID = jlib:make_jid(U, StateData#state.server, R),
|
||||
case acl:match_rule(StateData#state.access, JID) of
|
||||
allow ->
|
||||
case ejabberd_auth:check_password(
|
||||
@ -224,6 +225,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
{next_state, session_established,
|
||||
StateData#state{user = U,
|
||||
resource = R,
|
||||
jid = JID,
|
||||
pres_f = ?SETS:from_list(Fs),
|
||||
pres_t = ?SETS:from_list(Ts),
|
||||
privacy_list = PrivList}};
|
||||
@ -281,12 +283,14 @@ wait_for_sasl_auth({xmlstreamelement, El}, StateData) ->
|
||||
send_element(StateData,
|
||||
{xmlelement, "success",
|
||||
[{"xmlns", ?NS_SASL}], []}),
|
||||
{U, _, R} = jlib:string_to_jid(
|
||||
xml:get_attr_s(authzid, Props)),
|
||||
JID = #jid{user = U, resource = R} =
|
||||
jlib:string_to_jid(
|
||||
xml:get_attr_s(authzid, Props)),
|
||||
{next_state, wait_for_stream,
|
||||
StateData#state{authentificated = true,
|
||||
user = U,
|
||||
resource = R
|
||||
resource = R,
|
||||
jid = JID
|
||||
}};
|
||||
{continue, ServerOut, NewSASLState} ->
|
||||
send_element(StateData,
|
||||
@ -344,12 +348,13 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
|
||||
send_element(StateData,
|
||||
{xmlelement, "success",
|
||||
[{"xmlns", ?NS_SASL}], []}),
|
||||
{U, _, R} = jlib:string_to_jid(
|
||||
xml:get_attr_s(authzid, Props)),
|
||||
JID = #jid{user = U, resource = R} =
|
||||
jlib:string_to_jid(xml:get_attr_s(authzid, Props)),
|
||||
{next_state, wait_for_stream,
|
||||
StateData#state{authentificated = true,
|
||||
user = U,
|
||||
resource = R
|
||||
resource = R,
|
||||
jid = JID
|
||||
}};
|
||||
{continue, ServerOut, NewSASLState} ->
|
||||
send_element(StateData,
|
||||
@ -402,7 +407,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
|
||||
U = StateData#state.user,
|
||||
R = StateData#state.resource,
|
||||
io:format("SASLAUTH: ~p~n", [{U, R}]),
|
||||
JID = {U, ?MYNAME, R},
|
||||
JID = jlib:make_jid(U, StateData#state.server, R),
|
||||
case acl:match_rule(StateData#state.access, JID) of
|
||||
allow ->
|
||||
ejabberd_sm:open_session(U, R),
|
||||
@ -457,13 +462,14 @@ session_established({xmlstreamelement, El}, StateData) ->
|
||||
{xmlelement, Name, Attrs, Els} = El,
|
||||
User = StateData#state.user,
|
||||
Server = StateData#state.server,
|
||||
FromJID = {User,
|
||||
Server,
|
||||
StateData#state.resource},
|
||||
%FromJID = {User,
|
||||
% Server,
|
||||
% StateData#state.resource},
|
||||
FromJID = StateData#state.jid,
|
||||
To = xml:get_attr_s("to", Attrs),
|
||||
ToJID = case To of
|
||||
"" ->
|
||||
{User, Server, ""};
|
||||
jlib:make_jid(User, Server, "");
|
||||
_ ->
|
||||
jlib:string_to_jid(To)
|
||||
end,
|
||||
@ -476,7 +482,9 @@ session_established({xmlstreamelement, El}, StateData) ->
|
||||
case Name of
|
||||
"presence" ->
|
||||
case ToJID of
|
||||
{User, Server, ""} ->
|
||||
#jid{user = User,
|
||||
server = Server,
|
||||
resource = ""} ->
|
||||
?DEBUG("presence_update(~p,~n\t~p,~n\t~p)",
|
||||
[FromJID, El, StateData]),
|
||||
presence_update(FromJID, El, StateData);
|
||||
@ -573,7 +581,6 @@ handle_info(replaced, StateName, StateData) ->
|
||||
{stop, normal, StateData#state{user = ""}};
|
||||
handle_info({route, From, To, Packet}, StateName, StateData) ->
|
||||
{xmlelement, Name, Attrs, Els} = Packet,
|
||||
{FU, FS, FR} = From,
|
||||
{Pass, NewAttrs, NewState} =
|
||||
case Name of
|
||||
"presence" ->
|
||||
@ -694,9 +701,7 @@ terminate(Reason, StateName, StateData) ->
|
||||
_ ->
|
||||
ejabberd_sm:close_session(StateData#state.user,
|
||||
StateData#state.resource),
|
||||
From = {StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.resource},
|
||||
From = StateData#state.jid,
|
||||
Packet = {xmlelement, "presence", [{"type", "unavailable"}], []},
|
||||
ejabberd_sm:unset_presence(StateData#state.user,
|
||||
StateData#state.resource),
|
||||
@ -797,16 +802,17 @@ get_auth_tags([], U, P, D, R) ->
|
||||
|
||||
|
||||
process_presence_probe(From, To, StateData) ->
|
||||
LFrom = jlib:jid_tolower(From),
|
||||
case StateData#state.pres_last of
|
||||
undefined ->
|
||||
ok;
|
||||
_ ->
|
||||
Cond1 = (not StateData#state.pres_invis)
|
||||
and ?SETS:is_element(From, StateData#state.pres_f)
|
||||
and (not ?SETS:is_element(From, StateData#state.pres_i)),
|
||||
and ?SETS:is_element(LFrom, StateData#state.pres_f)
|
||||
and (not ?SETS:is_element(LFrom, StateData#state.pres_i)),
|
||||
Cond2 = StateData#state.pres_invis
|
||||
and ?SETS:is_element(From, StateData#state.pres_f)
|
||||
and ?SETS:is_element(From, StateData#state.pres_a),
|
||||
and ?SETS:is_element(LFrom, StateData#state.pres_f)
|
||||
and ?SETS:is_element(LFrom, StateData#state.pres_a),
|
||||
if
|
||||
Cond1 ->
|
||||
ejabberd_router:route(To, From,
|
||||
@ -934,14 +940,16 @@ presence_track(From, To, Packet, StateData) ->
|
||||
|
||||
presence_broadcast(From, JIDSet, Packet) ->
|
||||
lists:foreach(fun(JID) ->
|
||||
ejabberd_router:route(From, JID, Packet)
|
||||
ejabberd_router:route(
|
||||
From, jlib:make_jid(JID), Packet)
|
||||
end, ?SETS:to_list(JIDSet)).
|
||||
|
||||
presence_broadcast_to_trusted(From, T, A, Packet) ->
|
||||
lists:foreach(fun(JID) ->
|
||||
case ?SETS:is_element(JID, T) of
|
||||
true ->
|
||||
ejabberd_router:route(From, JID, Packet);
|
||||
ejabberd_router:route(
|
||||
From, jlib:make_jid(JID), Packet);
|
||||
_ ->
|
||||
ok
|
||||
end
|
||||
@ -949,12 +957,13 @@ presence_broadcast_to_trusted(From, T, A, Packet) ->
|
||||
|
||||
|
||||
presence_broadcast_first(From, StateData, Packet) ->
|
||||
{U, S, _} = From,
|
||||
?SETS:fold(fun(JID, X) ->
|
||||
ejabberd_router:route({U, S, ""}, JID,
|
||||
{xmlelement, "presence",
|
||||
[{"type", "probe"}],
|
||||
[]}),
|
||||
ejabberd_router:route(
|
||||
jlib:jid_replace_resource(From, ""),
|
||||
jlib:make_jid(JID),
|
||||
{xmlelement, "presence",
|
||||
[{"type", "probe"}],
|
||||
[]}),
|
||||
X
|
||||
end,
|
||||
[],
|
||||
@ -964,7 +973,9 @@ presence_broadcast_first(From, StateData, Packet) ->
|
||||
StateData;
|
||||
true ->
|
||||
As = ?SETS:fold(fun(JID, A) ->
|
||||
ejabberd_router:route(From, JID, Packet),
|
||||
ejabberd_router:route(From,
|
||||
jlib:make_jid(JID),
|
||||
Packet),
|
||||
?SETS:add_element(JID, A)
|
||||
end,
|
||||
StateData#state.pres_a,
|
||||
@ -1003,9 +1014,7 @@ roster_change(IJID, ISubscription, StateData) ->
|
||||
StateData#state{pres_f = FSet, pres_t = TSet};
|
||||
P ->
|
||||
?DEBUG("roster changed for ~p~n", [StateData#state.user]),
|
||||
From = {StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.resource},
|
||||
From = StateData#state.jid,
|
||||
Cond1 = (not StateData#state.pres_invis) and IsFrom,
|
||||
Cond2 = (not IsFrom)
|
||||
and (?SETS:is_element(LIJID, StateData#state.pres_a) or
|
||||
@ -1013,7 +1022,7 @@ roster_change(IJID, ISubscription, StateData) ->
|
||||
if
|
||||
Cond1 ->
|
||||
?DEBUG("C1: ~p~n", [LIJID]),
|
||||
ejabberd_router:route(From, IJID, P),
|
||||
ejabberd_router:route(From, jlib:make_jid(IJID), P),
|
||||
A = ?SETS:add_element(LIJID,
|
||||
StateData#state.pres_a),
|
||||
StateData#state{pres_a = A,
|
||||
@ -1021,7 +1030,7 @@ roster_change(IJID, ISubscription, StateData) ->
|
||||
pres_t = TSet};
|
||||
Cond2 ->
|
||||
?DEBUG("C2: ~p~n", [LIJID]),
|
||||
ejabberd_router:route(From, IJID,
|
||||
ejabberd_router:route(From, jlib:make_jid(IJID),
|
||||
{xmlelement, "presence",
|
||||
[{"type", "unavailable"}], []}),
|
||||
I = remove_element(LIJID,
|
||||
|
@ -71,7 +71,7 @@ do_route(State, From, To, Packet) ->
|
||||
?DEBUG("local route~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
|
||||
[From, To, Packet, 8]),
|
||||
case To of
|
||||
{"", _, ""} ->
|
||||
#jid{luser = "", lresource = ""} ->
|
||||
{xmlelement, Name, Attrs, Els} = Packet,
|
||||
case Name of
|
||||
"iq" ->
|
||||
@ -83,11 +83,12 @@ do_route(State, From, To, Packet) ->
|
||||
_ ->
|
||||
ok
|
||||
end;
|
||||
{"", _, _} ->
|
||||
#jid{luser = ""} ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_ITEM_NOT_FOUND),
|
||||
ejabberd_router ! {route,
|
||||
{"", State#state.mydomain, ""}, From, Err},
|
||||
ok;
|
||||
jlib:make_jid("", State#state.mydomain, ""),
|
||||
From,
|
||||
Err};
|
||||
_ ->
|
||||
ejabberd_sm ! {route, From, To, Packet}
|
||||
end.
|
||||
|
@ -22,6 +22,7 @@
|
||||
-export([start_link/0, init/0]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-record(route, {domain, node, pid}).
|
||||
-record(local_route, {domain, pid}).
|
||||
@ -101,8 +102,7 @@ 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,
|
||||
LDstDomain = jlib:tolower(DstDomain),
|
||||
#jid{lserver = LDstDomain} = To,
|
||||
case mnesia:dirty_read({local_route, LDstDomain}) of
|
||||
[] ->
|
||||
case mnesia:dirty_read({route, LDstDomain}) of
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
-include_lib("mnemosyne/include/mnemosyne.hrl").
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-record(s2s, {fromto, node, key}).
|
||||
-record(local_s2s, {fromto, pid}).
|
||||
@ -148,8 +149,8 @@ try_register(FromTo) ->
|
||||
do_route(From, To, Packet) ->
|
||||
?DEBUG("s2s manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
|
||||
[From, To, Packet, 8]),
|
||||
{_, MyServer, _} = From,
|
||||
{User, Server, Resource} = To,
|
||||
#jid{lserver = MyServer} = From,
|
||||
#jid{lserver = Server} = To,
|
||||
FromTo = {MyServer, Server},
|
||||
Key = randoms:get_string(),
|
||||
case find_connection(FromTo, Key) of
|
||||
|
@ -266,7 +266,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
|
||||
From = xml:get_attr_s("from", Attrs),
|
||||
FromJID1 = jlib:string_to_jid(From),
|
||||
FromJID = case FromJID1 of
|
||||
{Node, Server, Resource} ->
|
||||
#jid{lserver = Server} ->
|
||||
if Server == StateData#state.server -> FromJID1;
|
||||
true -> error
|
||||
end;
|
||||
|
@ -102,7 +102,7 @@ close_session(User, Resource) ->
|
||||
|
||||
|
||||
register_connection(User, Resource, Pid) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
UR = {LUser, Resource},
|
||||
F = fun() ->
|
||||
Ss = mnesia:wread({session, UR}),
|
||||
@ -132,7 +132,7 @@ register_connection(User, Resource, Pid) ->
|
||||
|
||||
|
||||
replace_my_connection(User, Resource) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
F = fun() ->
|
||||
UR = {LUser, Resource},
|
||||
Es = mnesia:read({local_session, UR}),
|
||||
@ -151,7 +151,7 @@ replace_my_connection(User, Resource) ->
|
||||
|
||||
|
||||
remove_connection(User, Resource) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
F = fun() ->
|
||||
UR = {LUser, Resource},
|
||||
mnesia:delete({local_session, UR}),
|
||||
@ -177,33 +177,34 @@ clean_table_from_bad_node(Node) ->
|
||||
do_route(From, To, Packet) ->
|
||||
?DEBUG("session manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
|
||||
[From, To, Packet, 8]),
|
||||
{User, Server, Resource} = To,
|
||||
#jid{user = User, server = Server, resource = Resource,
|
||||
luser = LUser, lserver = LServer, lresource = LResource} = To,
|
||||
{xmlelement, Name, Attrs, Els} = Packet,
|
||||
case Resource of
|
||||
"" ->
|
||||
case Name of
|
||||
"presence" ->
|
||||
{FU, FS, FR} = From,
|
||||
FromU = jlib:jid_replace_resource(From, ""),
|
||||
{Pass, Subsc} =
|
||||
case xml:get_attr_s("type", Attrs) of
|
||||
"subscribe" ->
|
||||
{mod_roster:in_subscription(User,
|
||||
{FU, FS, ""},
|
||||
FromU,
|
||||
subscribe),
|
||||
true};
|
||||
"subscribed" ->
|
||||
{mod_roster:in_subscription(User,
|
||||
{FU, FS, ""},
|
||||
FromU,
|
||||
subscribed),
|
||||
true};
|
||||
"unsubscribe" ->
|
||||
{mod_roster:in_subscription(User,
|
||||
{FU, FS, ""},
|
||||
FromU,
|
||||
unsubscribe),
|
||||
true};
|
||||
"unsubscribed" ->
|
||||
{mod_roster:in_subscription(User,
|
||||
{FU, FS, ""},
|
||||
FromU,
|
||||
unsubscribed),
|
||||
true};
|
||||
_ ->
|
||||
@ -211,8 +212,6 @@ do_route(From, To, Packet) ->
|
||||
end,
|
||||
if Pass ->
|
||||
LFrom = jlib:jid_tolower(From),
|
||||
LUser = jlib:tolower(User),
|
||||
LServer = jlib:tolower(Server),
|
||||
Resources = get_user_resources(User),
|
||||
if
|
||||
Resources /= [] ->
|
||||
@ -223,7 +222,7 @@ do_route(From, To, Packet) ->
|
||||
ejabberd_sm !
|
||||
{route,
|
||||
From,
|
||||
{User, Server, R},
|
||||
jlib:jid_replace_resource(To, R),
|
||||
Packet};
|
||||
true ->
|
||||
ok
|
||||
@ -250,21 +249,25 @@ do_route(From, To, Packet) ->
|
||||
fun(R) ->
|
||||
ejabberd_sm ! {route,
|
||||
From,
|
||||
{User, Server, R},
|
||||
jlib:jid_replace_resource(To, R),
|
||||
Packet}
|
||||
end, get_user_resources(User));
|
||||
_ ->
|
||||
ok
|
||||
end;
|
||||
_ ->
|
||||
LUR = {jlib:tolower(User), Resource},
|
||||
LUR = {LUser, LResource},
|
||||
Sess = mnesia:dirty_read({session, LUR}),
|
||||
case Sess of
|
||||
[] ->
|
||||
if
|
||||
Name == "message" ->
|
||||
case Name of
|
||||
"message" ->
|
||||
route_message(From, To, Packet);
|
||||
true ->
|
||||
"iq" ->
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERR_RECIPIENT_UNAVAILABLE),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
_ ->
|
||||
?DEBUG("packet droped~n", [])
|
||||
end;
|
||||
[Ses] ->
|
||||
@ -282,10 +285,10 @@ do_route(From, To, Packet) ->
|
||||
end.
|
||||
|
||||
route_message(From, To, Packet) ->
|
||||
{User, Server, Resource} = To,
|
||||
case catch lists:max(get_user_present_resources(User)) of
|
||||
#jid{luser = LUser} = To,
|
||||
case catch lists:max(get_user_present_resources(LUser)) of
|
||||
{'EXIT', _} ->
|
||||
case ejabberd_auth:is_user_exists(User) of
|
||||
case ejabberd_auth:is_user_exists(LUser) of
|
||||
true ->
|
||||
case catch mod_offline:store_packet(From, To, Packet) of
|
||||
{'EXIT', _} ->
|
||||
@ -303,7 +306,7 @@ route_message(From, To, Packet) ->
|
||||
{_, R} ->
|
||||
ejabberd_sm ! {route,
|
||||
From,
|
||||
{User, Server, R},
|
||||
jlib:jid_replace_resource(To, R),
|
||||
Packet}
|
||||
end.
|
||||
|
||||
@ -311,7 +314,7 @@ route_message(From, To, Packet) ->
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
get_user_resources(User) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
case catch mnesia:dirty_index_read(session, LUser, #session.user) of
|
||||
{'EXIT', Reason} ->
|
||||
[];
|
||||
@ -325,7 +328,7 @@ get_user_resources(User) ->
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
set_presence(User, Resource, Priority) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
F = fun() ->
|
||||
UR = {User, Resource},
|
||||
mnesia:write(#presence{ur = UR, user = LUser,
|
||||
@ -334,15 +337,14 @@ set_presence(User, Resource, Priority) ->
|
||||
mnesia:transaction(F).
|
||||
|
||||
unset_presence(User, Resource) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
F = fun() ->
|
||||
UR = {User, Resource},
|
||||
mnesia:delete({presence, UR})
|
||||
end,
|
||||
mnesia:transaction(F).
|
||||
|
||||
get_user_present_resources(User) ->
|
||||
LUser = jlib:tolower(User),
|
||||
get_user_present_resources(LUser) ->
|
||||
case catch mnesia:dirty_index_read(presence, LUser, #presence.user) of
|
||||
{'EXIT', Reason} ->
|
||||
[];
|
||||
@ -367,7 +369,7 @@ process_iq(From, To, Packet) ->
|
||||
{iq, ID, Type, XMLNS, SubEl} ->
|
||||
case ets:lookup(sm_iqtable, XMLNS) of
|
||||
[{_, Module, Function}] ->
|
||||
ResIQ = apply(Module, Function, [From, To, IQ]),
|
||||
ResIQ = Module:Function(From, To, IQ),
|
||||
if
|
||||
ResIQ /= ignore ->
|
||||
ejabberd_router ! {route,
|
||||
|
97
src/jlib.erl
97
src/jlib.erl
@ -18,12 +18,18 @@
|
||||
replace_from_to_attrs/3,
|
||||
replace_from_to/3,
|
||||
remove_attr/2,
|
||||
make_jid/3,
|
||||
make_jid/1,
|
||||
string_to_jid/1,
|
||||
jid_to_string/1,
|
||||
is_nodename/1,
|
||||
tolower/1,
|
||||
nodeprep/1,
|
||||
nameprep/1,
|
||||
resourceprep/1,
|
||||
jid_tolower/1,
|
||||
jid_remove_resource/1,
|
||||
jid_replace_resource/2,
|
||||
get_iq_namespace/1,
|
||||
iq_query_info/1,
|
||||
is_iq_request_type/1,
|
||||
@ -130,6 +136,30 @@ remove_attr(Attr, {xmlelement, Name, Attrs, Els}) ->
|
||||
NewAttrs = lists:keydelete(Attr, 1, Attrs),
|
||||
{xmlelement, Name, NewAttrs, Els}.
|
||||
|
||||
|
||||
make_jid(User, Server, Resource) ->
|
||||
case stringprep:nodeprep(User) of
|
||||
error -> error;
|
||||
LUser ->
|
||||
case stringprep:nameprep(Server) of
|
||||
error -> error;
|
||||
LServer ->
|
||||
case stringprep:resourceprep(Resource) of
|
||||
error -> error;
|
||||
LResource ->
|
||||
#jid{user = User,
|
||||
server = Server,
|
||||
resource = Resource,
|
||||
luser = LUser,
|
||||
lserver = LServer,
|
||||
lresource = LResource}
|
||||
end
|
||||
end
|
||||
end.
|
||||
|
||||
make_jid({User, Server, Resource}) ->
|
||||
make_jid(User, Server, Resource).
|
||||
|
||||
string_to_jid(J) ->
|
||||
string_to_jid1(J, "").
|
||||
|
||||
@ -157,7 +187,7 @@ string_to_jid1([C | J], N) ->
|
||||
string_to_jid1([], "") ->
|
||||
error;
|
||||
string_to_jid1([], N) ->
|
||||
{"", lists:reverse(N), ""}.
|
||||
make_jid("", lists:reverse(N), "").
|
||||
|
||||
string_to_jid2([$/ | J], N, "") ->
|
||||
error;
|
||||
@ -168,13 +198,15 @@ string_to_jid2([C | J], N, S) ->
|
||||
string_to_jid2([], N, "") ->
|
||||
error;
|
||||
string_to_jid2([], N, S) ->
|
||||
{N, lists:reverse(S), ""}.
|
||||
make_jid(N, lists:reverse(S), "").
|
||||
|
||||
string_to_jid3([C | J], N, S, R) ->
|
||||
string_to_jid3(J, N, S, [C | R]);
|
||||
string_to_jid3([], N, S, R) ->
|
||||
{N, S, lists:reverse(R)}.
|
||||
make_jid(N, S, lists:reverse(R)).
|
||||
|
||||
jid_to_string(#jid{user = User, server = Server, resource = Resource}) ->
|
||||
jid_to_string({User, Server, Resource});
|
||||
jid_to_string({Node, Server, Resource}) ->
|
||||
S1 = case Node of
|
||||
"" ->
|
||||
@ -256,13 +288,34 @@ tolower([]) ->
|
||||
% [].
|
||||
|
||||
|
||||
nodeprep(S) ->
|
||||
stringprep:nodeprep(S).
|
||||
|
||||
nameprep(S) ->
|
||||
stringprep:nameprep(S).
|
||||
|
||||
resourceprep(S) ->
|
||||
stringprep:resourceprep(S).
|
||||
|
||||
|
||||
jid_tolower(#jid{luser = U, lserver = S, lresource = R}) ->
|
||||
{U, S, R};
|
||||
jid_tolower({U, S, R}) ->
|
||||
{tolower(U), tolower(S), R}.
|
||||
|
||||
jid_remove_resource(#jid{} = JID) ->
|
||||
JID#jid{resource = "", lresource = ""};
|
||||
jid_remove_resource({U, S, R}) ->
|
||||
{U, S, ""}.
|
||||
|
||||
jid_replace_resource(JID, Resource) ->
|
||||
case stringprep:resourceprep(Resource) of
|
||||
error -> error;
|
||||
LResource ->
|
||||
JID#jid{resource = Resource, lresource = LResource}
|
||||
end.
|
||||
|
||||
|
||||
get_iq_namespace({xmlelement, Name, Attrs, Els}) when Name == "iq" ->
|
||||
case xml:remove_cdata(Els) of
|
||||
[{xmlelement, Name2, Attrs2, Els2}] ->
|
||||
@ -276,29 +329,29 @@ get_iq_namespace(_) ->
|
||||
iq_query_info({xmlelement, Name, Attrs, Els}) when Name == "iq" ->
|
||||
ID = xml:get_attr_s("id", Attrs),
|
||||
Type = xml:get_attr_s("type", Attrs),
|
||||
case xml:remove_cdata(Els) of
|
||||
[{xmlelement, Name2, Attrs2, Els2}] ->
|
||||
XMLNS = xml:get_attr_s("xmlns", Attrs2),
|
||||
Type1 = case Type of
|
||||
"set" -> set;
|
||||
"get" -> get;
|
||||
"result" -> reply;
|
||||
"error" -> reply;
|
||||
_ -> invalid
|
||||
end,
|
||||
if
|
||||
(Type1 /= invalid) and (Type1 /= reply) and (XMLNS /= "") ->
|
||||
{iq, ID, Type1, XMLNS, {xmlelement, Name2, Attrs2, Els2}};
|
||||
true ->
|
||||
Type1 = case Type of
|
||||
"set" -> set;
|
||||
"get" -> get;
|
||||
"result" -> reply;
|
||||
"error" -> reply;
|
||||
_ -> invalid
|
||||
end,
|
||||
if
|
||||
(Type1 /= invalid) and (Type1 /= reply) ->
|
||||
case xml:remove_cdata(Els) of
|
||||
[{xmlelement, Name2, Attrs2, Els2}] ->
|
||||
XMLNS = xml:get_attr_s("xmlns", Attrs2),
|
||||
if
|
||||
Type1 == reply ->
|
||||
reply;
|
||||
XMLNS /= "" ->
|
||||
{iq, ID, Type1, XMLNS, {xmlelement, Name2, Attrs2, Els2}};
|
||||
true ->
|
||||
invalid
|
||||
end
|
||||
end;
|
||||
_ ->
|
||||
invalid
|
||||
end;
|
||||
_ ->
|
||||
invalid
|
||||
true ->
|
||||
Type1
|
||||
end;
|
||||
iq_query_info(_) ->
|
||||
not_iq.
|
||||
|
@ -138,4 +138,6 @@
|
||||
% ?STREAM_ERROR("")).
|
||||
|
||||
|
||||
-record(jid, {user, server, resource,
|
||||
luser, lserver, lresource}).
|
||||
|
||||
|
@ -436,7 +436,7 @@ get_stopped_nodes(Lang) ->
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
process_sm_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
{User, _, _} = To,
|
||||
#jid{user = User} = To,
|
||||
case {acl:match_rule(configure, From), Type} of
|
||||
{deny, _} ->
|
||||
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
|
@ -57,7 +57,7 @@ loop(Host) ->
|
||||
|
||||
|
||||
do_route(Host, From, To, Packet) ->
|
||||
{ChanServ, _, Resource} = To,
|
||||
#jid{user = ChanServ, resource = Resource} = To,
|
||||
case ChanServ of
|
||||
"" ->
|
||||
case Resource of
|
||||
@ -75,12 +75,11 @@ do_route(Host, From, To, Packet) ->
|
||||
iq_data(From, To, ID, XMLNS, Type, SubEl);
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, "503", "Service Unavailable"),
|
||||
Packet, ?ERR_SERVICE_UNAVAILABLE),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end;
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
"406", "Not Acceptable"),
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end;
|
||||
_ ->
|
||||
@ -115,8 +114,7 @@ do_route(Host, From, To, Packet) ->
|
||||
case ets:lookup(irc_connection, {From, Server}) of
|
||||
[] ->
|
||||
Err = jlib:make_error_reply(
|
||||
Packet,
|
||||
"503", "Service Unavailable"),
|
||||
Packet, ?ERR_SERVICE_UNAVAILABLE),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
[R] ->
|
||||
Pid = R#irc_connection.pid,
|
||||
@ -128,7 +126,7 @@ do_route(Host, From, To, Packet) ->
|
||||
end;
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, "406", "Not Acceptable"),
|
||||
Packet, ?ERR_BAD_REQUEST),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end
|
||||
end
|
||||
@ -185,9 +183,7 @@ process_iq_data(From, To, ID, XMLNS, Type, SubEl) ->
|
||||
case XData of
|
||||
invalid ->
|
||||
{iq, ID, error, XMLNS,
|
||||
[SubEl, {xmlelement, "error",
|
||||
[{"code", "400"}],
|
||||
[{xmlcdata, "Bad Request"}]}]};
|
||||
[SubEl, ?ERR_BAD_REQUEST]};
|
||||
_ ->
|
||||
Node =
|
||||
string:tokens(
|
||||
@ -227,8 +223,8 @@ process_iq_data(From, To, ID, XMLNS, Type, SubEl) ->
|
||||
|
||||
|
||||
get_form(From, [], Lang) ->
|
||||
{User, Server, _} = From,
|
||||
{LUser, LServer, _} = jlib:jid_tolower(From),
|
||||
#jid{user = User, server = Server,
|
||||
luser = LUser, lserver = LServer} = From,
|
||||
Customs =
|
||||
case catch mnesia:dirty_read({irc_custom, {LUser, LServer}}) of
|
||||
{'EXIT', Reason} ->
|
||||
@ -345,8 +341,8 @@ set_form(_, _, Lang, XData) ->
|
||||
|
||||
|
||||
get_user_and_encoding(From, IRCServer) ->
|
||||
{User, Server, _} = From,
|
||||
{LUser, LServer, _} = jlib:jid_tolower(From),
|
||||
#jid{user = User, server = Server,
|
||||
luser = LUser, lserver = LServer} = From,
|
||||
case catch mnesia:dirty_read({irc_custom, {LUser, LServer}}) of
|
||||
{'EXIT', Reason} ->
|
||||
{User, ?DEFAULT_IRC_ENCODING};
|
||||
|
@ -36,7 +36,7 @@
|
||||
channels = dict:new(),
|
||||
inbuf = "", outbuf = ""}).
|
||||
|
||||
-define(DBGFSM, true).
|
||||
%-define(DBGFSM, true).
|
||||
|
||||
-ifdef(DBGFSM).
|
||||
-define(FSMOPTS, [{debug, [trace]}]).
|
||||
@ -411,7 +411,7 @@ handle_info({ircstring, [$: | String]}, StateName, StateData) ->
|
||||
[From, "NICK", Nick | _] ->
|
||||
process_nick(StateData, From, Nick);
|
||||
_ ->
|
||||
io:format("unknown irc command '~s'~n", [String]),
|
||||
?DEBUG("unknown irc command '~s'~n", [String]),
|
||||
StateData
|
||||
end,
|
||||
NewStateData1 =
|
||||
@ -431,7 +431,7 @@ handle_info({ircstring, [$E, $R, $R, $O, $R | _] = String},
|
||||
|
||||
|
||||
handle_info({ircstring, String}, StateName, StateData) ->
|
||||
io:format("unknown irc command '~s'~n", [String]),
|
||||
?DEBUG("unknown irc command '~s'~n", [String]),
|
||||
{next_state, StateName, StateData};
|
||||
|
||||
|
||||
@ -441,7 +441,7 @@ handle_info({send_text, Text}, StateName, StateData) ->
|
||||
handle_info({tcp, Socket, Data}, StateName, StateData) ->
|
||||
Buf = StateData#state.inbuf ++ binary_to_list(Data),
|
||||
{ok, Strings} = regexp:split([C || C <- Buf, C /= $\r], "\n"),
|
||||
io:format("strings=~p~n", [Strings]),
|
||||
?DEBUG("strings=~p~n", [Strings]),
|
||||
NewBuf = process_lines(StateData#state.encoding, Strings),
|
||||
{next_state, StateName, StateData#state{inbuf = NewBuf}};
|
||||
handle_info({tcp_closed, Socket}, StateName, StateData) ->
|
||||
@ -499,7 +499,7 @@ receiver(Socket, C2SPid, XMLStreamPid) ->
|
||||
|
||||
send_text(#state{socket = Socket, encoding = Encoding}, Text) ->
|
||||
CText = iconv:convert("utf-8", Encoding, lists:flatten(Text)),
|
||||
%io:format("IRC OUTu: ~s~nIRC OUTk: ~s~n", [Text, CText]),
|
||||
%?DEBUG("IRC OUTu: ~s~nIRC OUTk: ~s~n", [Text, CText]),
|
||||
gen_tcp:send(Socket, CText).
|
||||
|
||||
|
||||
|
@ -59,6 +59,7 @@
|
||||
|
||||
-record(state, {room,
|
||||
host,
|
||||
jid,
|
||||
config = #config{},
|
||||
users = ?DICT:new(),
|
||||
affiliations = ?DICT:new(),
|
||||
@ -117,11 +118,13 @@ init([Host, Room, Creator, Nick]) ->
|
||||
LCreator = jlib:jid_tolower(Creator),
|
||||
State = set_affiliation(Creator, owner,
|
||||
#state{host = Host,
|
||||
room = Room}),
|
||||
room = Room,
|
||||
jid = jlib:make_jid(Room, Host, "")}),
|
||||
{ok, normal_state, State};
|
||||
init([Host, Room, Opts]) ->
|
||||
State = set_opts(Opts, #state{host = Host,
|
||||
room = Room}),
|
||||
room = Room,
|
||||
jid = jlib:make_jid(Room, Host, "")}),
|
||||
{ok, normal_state, State}.
|
||||
|
||||
%%----------------------------------------------------------------------
|
||||
@ -173,9 +176,9 @@ normal_state({route, From, "",
|
||||
lists:foreach(
|
||||
fun({LJID, Info}) ->
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room,
|
||||
StateData#state.host,
|
||||
FromNick},
|
||||
jlib:jid_replace_resource(
|
||||
StateData#state.jid,
|
||||
FromNick),
|
||||
Info#user.jid,
|
||||
Packet)
|
||||
end,
|
||||
@ -189,8 +192,7 @@ normal_state({route, From, "",
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERR_NOT_ALLOWED),
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room,
|
||||
StateData#state.host, ""},
|
||||
StateData#state.jid,
|
||||
From, Err),
|
||||
{next_state, normal_state, StateData}
|
||||
end;
|
||||
@ -198,7 +200,7 @@ normal_state({route, From, "",
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERR_NOT_ALLOWED),
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room, StateData#state.host, ""},
|
||||
StateData#state.jid,
|
||||
From, Err),
|
||||
{next_state, normal_state, StateData}
|
||||
end;
|
||||
@ -223,7 +225,7 @@ normal_state({route, From, "",
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERR_NOT_ALLOWED),
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room, StateData#state.host, ""},
|
||||
StateData#state.jid,
|
||||
From, Err),
|
||||
{next_state, normal_state, StateData};
|
||||
IJID ->
|
||||
@ -249,15 +251,14 @@ normal_state({route, From, "",
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERR_NOT_ALLOWED),
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room, StateData#state.host, ""},
|
||||
StateData#state.jid,
|
||||
From, Err),
|
||||
{next_state, normal_state, StateData}
|
||||
end;
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERR_NOT_ALLOWED),
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room, StateData#state.host, ""}, From, Err),
|
||||
ejabberd_router:route(StateData#state.jid, From, Err),
|
||||
{next_state, normal_state, StateData}
|
||||
end;
|
||||
|
||||
@ -293,9 +294,7 @@ normal_state({route, From, "",
|
||||
[SubEl, Error]},
|
||||
StateData}
|
||||
end,
|
||||
ejabberd_router:route({StateData#state.room,
|
||||
StateData#state.host,
|
||||
""},
|
||||
ejabberd_router:route(StateData#state.jid,
|
||||
From,
|
||||
jlib:iq_to_xml(IQRes)),
|
||||
case NewStateData of
|
||||
@ -307,8 +306,7 @@ normal_state({route, From, "",
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room, StateData#state.host, ""}, From, Err),
|
||||
ejabberd_router:route(StateData#state.jid, From, Err),
|
||||
{next_state, normal_state, StateData}
|
||||
end;
|
||||
|
||||
@ -353,9 +351,9 @@ normal_state({route, From, Nick,
|
||||
Packet,
|
||||
?ERR_MUC_NICK_CHANGE_CONFLICT),
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room,
|
||||
StateData#state.host,
|
||||
Nick}, % TODO: s/Nick/""/
|
||||
jlib:jid_replace_resource(
|
||||
StateData#state.jid,
|
||||
Nick), % TODO: s/Nick/""/
|
||||
From, Err),
|
||||
StateData;
|
||||
_ ->
|
||||
@ -411,18 +409,18 @@ normal_state({route, From, ToNick,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERR_ITEM_NOT_FOUND),
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room,
|
||||
StateData#state.host,
|
||||
ToNick},
|
||||
jlib:jid_replace_resource(
|
||||
StateData#state.jid,
|
||||
ToNick),
|
||||
From, Err);
|
||||
ToJID ->
|
||||
{ok, #user{nick = FromNick}} =
|
||||
?DICT:find(jlib:jid_tolower(From),
|
||||
StateData#state.users),
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room,
|
||||
StateData#state.host,
|
||||
FromNick},
|
||||
jlib:jid_replace_resource(
|
||||
StateData#state.jid,
|
||||
FromNick),
|
||||
ToJID, Packet)
|
||||
end,
|
||||
{next_state, normal_state, StateData};
|
||||
@ -430,9 +428,9 @@ normal_state({route, From, ToNick,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERR_NOT_ALLOWED),
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room,
|
||||
StateData#state.host,
|
||||
ToNick}, From, Err),
|
||||
jlib:jid_replace_resource(
|
||||
StateData#state.jid,
|
||||
ToNick), From, Err),
|
||||
{next_state, normal_state, StateData}
|
||||
end
|
||||
end;
|
||||
@ -448,21 +446,22 @@ normal_state({route, From, ToNick,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERR_ITEM_NOT_FOUND),
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room, StateData#state.host, ToNick},
|
||||
jlib:jid_replace_resource(StateData#state.jid, ToNick),
|
||||
From, Err);
|
||||
ToJID ->
|
||||
{ok, #user{nick = FromNick}} =
|
||||
?DICT:find(jlib:jid_tolower(From),
|
||||
StateData#state.users),
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room, StateData#state.host, FromNick},
|
||||
jlib:jid_replace_resource(StateData#state.jid, FromNick),
|
||||
ToJID, Packet)
|
||||
end;
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERR_NOT_ALLOWED),
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room, StateData#state.host, ToNick}, From, Err)
|
||||
jlib:jid_replace_resource(StateData#state.jid, ToNick), From,
|
||||
Err)
|
||||
end,
|
||||
{next_state, normal_state, StateData};
|
||||
|
||||
@ -490,9 +489,7 @@ handle_event({service_message, Msg}, StateName, StateData) ->
|
||||
lists:foreach(
|
||||
fun({LJID, Info}) ->
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room,
|
||||
StateData#state.host,
|
||||
""},
|
||||
StateData#state.jid,
|
||||
Info#user.jid,
|
||||
MessagePkt)
|
||||
end,
|
||||
@ -792,9 +789,8 @@ add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) ->
|
||||
true ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_MUC_NICK_CONFLICT),
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room,
|
||||
StateData#state.host,
|
||||
Nick}, % TODO: s/Nick/""/
|
||||
% TODO: s/Nick/""/
|
||||
jlib:jid_replace_resource(StateData#state.jid, Nick),
|
||||
From, Err),
|
||||
StateData;
|
||||
_ ->
|
||||
@ -809,7 +805,7 @@ add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) ->
|
||||
_ -> ?ERR_MUC_NOT_MEMBER
|
||||
end),
|
||||
ejabberd_router:route( % TODO: s/Nick/""/
|
||||
{StateData#state.room, StateData#state.host, Nick},
|
||||
jlib:jid_replace_resource(StateData#state.jid, Nick),
|
||||
From, Err),
|
||||
StateData;
|
||||
_ ->
|
||||
@ -833,7 +829,8 @@ add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) ->
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERR_MUC_BAD_PASSWORD),
|
||||
ejabberd_router:route( % TODO: s/Nick/""/
|
||||
{StateData#state.room, StateData#state.host, Nick},
|
||||
jlib:jid_replace_resource(
|
||||
StateData#state.jid, Nick),
|
||||
From, Err),
|
||||
StateData
|
||||
end
|
||||
@ -922,7 +919,7 @@ send_new_presence(NJID, StateData) ->
|
||||
[{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
|
||||
[{xmlelement, "item", ItemAttrs, []}]}]),
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room, StateData#state.host, Nick},
|
||||
jlib:jid_replace_resource(StateData#state.jid, Nick),
|
||||
Info#user.jid,
|
||||
Packet)
|
||||
end, ?DICT:to_list(StateData#state.users)).
|
||||
@ -963,7 +960,8 @@ send_existing_presences(ToJID, StateData) ->
|
||||
[{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
|
||||
[{xmlelement, "item", ItemAttrs, []}]}]),
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room, StateData#state.host, FromNick},
|
||||
jlib:jid_replace_resource(
|
||||
StateData#state.jid, FromNick),
|
||||
RealToJID,
|
||||
Packet)
|
||||
end
|
||||
@ -1033,11 +1031,11 @@ send_nick_changing(JID, OldNick, StateData) ->
|
||||
[{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
|
||||
[{xmlelement, "item", ItemAttrs2, []}]}]),
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room, StateData#state.host, OldNick},
|
||||
jlib:jid_replace_resource(StateData#state.jid, OldNick),
|
||||
Info#user.jid,
|
||||
Packet1),
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room, StateData#state.host, Nick},
|
||||
jlib:jid_replace_resource(StateData#state.jid, Nick),
|
||||
Info#user.jid,
|
||||
Packet2)
|
||||
end, ?DICT:to_list(StateData#state.users)).
|
||||
@ -1086,7 +1084,7 @@ send_history(JID, StateData) ->
|
||||
lists:foldl(
|
||||
fun({Nick, Packet, HaveSubject}, B) ->
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room, StateData#state.host, Nick},
|
||||
jlib:jid_replace_resource(StateData#state.jid, Nick),
|
||||
JID,
|
||||
Packet),
|
||||
B or HaveSubject
|
||||
@ -1105,7 +1103,7 @@ send_subject(JID, StateData) ->
|
||||
[{xmlcdata,
|
||||
Nick ++ " has set the topic to: " ++ Subject}]}]},
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room, StateData#state.host, ""},
|
||||
StateData#state.jid,
|
||||
JID,
|
||||
Packet)
|
||||
end.
|
||||
@ -1123,7 +1121,7 @@ send_join_messages_end(JID, StateData) ->
|
||||
[{xmlelement, "body", [],
|
||||
[{xmlcdata, "-"}]}]},
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room, StateData#state.host, ""},
|
||||
StateData#state.jid,
|
||||
JID,
|
||||
Packet).
|
||||
|
||||
@ -1550,7 +1548,7 @@ send_kickban_presence1(UJID, Reason, Code, StateData) ->
|
||||
[{xmlelement, "item", ItemAttrs, ItemEls},
|
||||
{xmlelement, "status", [{"code", Code}], []}]}]},
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room, StateData#state.host, Nick},
|
||||
jlib:jid_replace_resource(StateData#state.jid, Nick),
|
||||
Info#user.jid,
|
||||
Packet)
|
||||
end, ?DICT:to_list(StateData#state.users)).
|
||||
@ -1842,7 +1840,7 @@ destroy_room(DEls, StateData) ->
|
||||
{xmlelement, "destroy", [],
|
||||
DEls}]}]},
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room, StateData#state.host, Nick},
|
||||
jlib:jid_replace_resource(StateData#state.jid, Nick),
|
||||
Info#user.jid,
|
||||
Packet)
|
||||
end, ?DICT:to_list(StateData#state.users)),
|
||||
@ -1950,9 +1948,7 @@ check_invitation(From, Els, StateData) ->
|
||||
""})}],
|
||||
[{xmlcdata, Reason}]}]},
|
||||
ejabberd_router:route(
|
||||
{StateData#state.room,
|
||||
StateData#state.host,
|
||||
""},
|
||||
StateData#state.jid,
|
||||
JID,
|
||||
Msg),
|
||||
JID;
|
||||
|
@ -66,8 +66,7 @@ store_packet(From, To, Packet) ->
|
||||
true = is_process_alive(whereis(?PROCNAME)),
|
||||
case check_event(From, To, Packet) of
|
||||
true ->
|
||||
{User, Server, Resource} = To,
|
||||
LUser = jlib:tolower(User),
|
||||
#jid{luser = LUser} = To,
|
||||
TimeStamp = now(),
|
||||
?PROCNAME ! #offline_msg{user = LUser,
|
||||
timestamp = TimeStamp,
|
||||
@ -125,7 +124,7 @@ find_x_event([El | Els]) ->
|
||||
|
||||
|
||||
resend_offline_messages(User) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
F = fun() ->
|
||||
Rs = mnesia:read({offline_msg, LUser}),
|
||||
mnesia:delete({offline_msg, LUser}),
|
||||
@ -152,7 +151,7 @@ resend_offline_messages(User) ->
|
||||
end.
|
||||
|
||||
remove_user(User) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
F = fun() ->
|
||||
mnesia:delete({offline_msg, LUser})
|
||||
end,
|
||||
|
@ -61,7 +61,7 @@ start(Opts) ->
|
||||
%
|
||||
process_iq(From, To, IQ) ->
|
||||
{iq, ID, Type, XMLNS, SubEl} = IQ,
|
||||
{_, Server, _} = From,
|
||||
#jid{lserver = Server} = From,
|
||||
Res =
|
||||
case ?MYNAME of
|
||||
Server ->
|
||||
@ -85,16 +85,16 @@ process_iq(From, To, IQ) ->
|
||||
|
||||
process_iq_get(From, To, {iq, ID, Type, XMLNS, SubEl},
|
||||
#userlist{name = Active}) ->
|
||||
{User, _, _} = From,
|
||||
#jid{luser = LUser} = From,
|
||||
{xmlelement, _, _, Els} = SubEl,
|
||||
case xml:remove_cdata(Els) of
|
||||
[] ->
|
||||
process_lists_get(User, Active);
|
||||
process_lists_get(LUser, Active);
|
||||
[{xmlelement, Name, Attrs, SubEls}] ->
|
||||
case Name of
|
||||
"list" ->
|
||||
ListName = xml:get_attr("name", Attrs),
|
||||
process_list_get(User, ListName);
|
||||
process_list_get(LUser, ListName);
|
||||
_ ->
|
||||
{error, ?ERR_BAD_REQUEST}
|
||||
end;
|
||||
@ -103,8 +103,7 @@ process_iq_get(From, To, {iq, ID, Type, XMLNS, SubEl},
|
||||
end.
|
||||
|
||||
|
||||
process_lists_get(User, Active) ->
|
||||
LUser = jlib:tolower(User),
|
||||
process_lists_get(LUser, Active) ->
|
||||
case catch mnesia:dirty_read(privacy, LUser) of
|
||||
{'EXIT', Reason} ->
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
@ -143,13 +142,13 @@ process_lists_get(User, Active) ->
|
||||
end
|
||||
end.
|
||||
|
||||
process_list_get(User, {value, Name}) ->
|
||||
LUser = jlib:tolower(User),
|
||||
case catch mnesia:dirty_read(privacy, User) of
|
||||
process_list_get(LUser, {value, Name}) ->
|
||||
case catch mnesia:dirty_read(privacy, LUser) of
|
||||
{'EXIT', Reason} ->
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
[] ->
|
||||
{result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], []}]};
|
||||
{error, ?ERR_ITEM_NOT_FOUND};
|
||||
%{result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], []}]};
|
||||
[#privacy{lists = Lists}] ->
|
||||
case lists:keysearch(Name, 1, Lists) of
|
||||
{value, {_, List}} ->
|
||||
@ -163,7 +162,7 @@ process_list_get(User, {value, Name}) ->
|
||||
end
|
||||
end;
|
||||
|
||||
process_list_get(_User, false) ->
|
||||
process_list_get(_LUser, false) ->
|
||||
{error, ?ERR_BAD_REQUEST}.
|
||||
|
||||
item_to_xml(Item) ->
|
||||
@ -250,18 +249,18 @@ list_to_action(S) ->
|
||||
|
||||
|
||||
process_iq_set(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
{User, _, _} = From,
|
||||
#jid{luser = LUser} = From,
|
||||
{xmlelement, _, _, Els} = SubEl,
|
||||
case xml:remove_cdata(Els) of
|
||||
[{xmlelement, Name, Attrs, SubEls}] ->
|
||||
ListName = xml:get_attr("name", Attrs),
|
||||
case Name of
|
||||
"list" ->
|
||||
process_list_set(User, ListName, xml:remove_cdata(SubEls));
|
||||
process_list_set(LUser, ListName, xml:remove_cdata(SubEls));
|
||||
"active" ->
|
||||
process_active_set(User, ListName);
|
||||
process_active_set(LUser, ListName);
|
||||
"default" ->
|
||||
process_default_set(User, ListName);
|
||||
process_default_set(LUser, ListName);
|
||||
_ ->
|
||||
{error, ?ERR_BAD_REQUEST}
|
||||
end;
|
||||
@ -270,8 +269,7 @@ process_iq_set(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
end.
|
||||
|
||||
|
||||
process_default_set(User, {value, Name}) ->
|
||||
LUser = jlib:tolower(User),
|
||||
process_default_set(LUser, {value, Name}) ->
|
||||
F = fun() ->
|
||||
case mnesia:read({privacy, LUser}) of
|
||||
[] ->
|
||||
@ -296,8 +294,7 @@ process_default_set(User, {value, Name}) ->
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR}
|
||||
end;
|
||||
|
||||
process_default_set(User, false) ->
|
||||
LUser = jlib:tolower(User),
|
||||
process_default_set(LUser, false) ->
|
||||
F = fun() ->
|
||||
case mnesia:read({privacy, LUser}) of
|
||||
[] ->
|
||||
@ -317,8 +314,7 @@ process_default_set(User, false) ->
|
||||
end.
|
||||
|
||||
|
||||
process_active_set(User, {value, Name}) ->
|
||||
LUser = jlib:tolower(User),
|
||||
process_active_set(LUser, {value, Name}) ->
|
||||
case catch mnesia:dirty_read(privacy, LUser) of
|
||||
[] ->
|
||||
{error, ?ERR_ITEM_NOT_FOUND};
|
||||
@ -331,7 +327,7 @@ process_active_set(User, {value, Name}) ->
|
||||
end
|
||||
end;
|
||||
|
||||
process_active_set(User, false) ->
|
||||
process_active_set(LUser, false) ->
|
||||
{result, [], #userlist{}}.
|
||||
|
||||
|
||||
@ -339,8 +335,7 @@ process_active_set(User, false) ->
|
||||
|
||||
|
||||
|
||||
process_list_set(User, {value, Name}, Els) ->
|
||||
LUser = jlib:tolower(User),
|
||||
process_list_set(LUser, {value, Name}, Els) ->
|
||||
case parse_items(Els) of
|
||||
false ->
|
||||
{error, ?ERR_BAD_REQUEST};
|
||||
@ -369,8 +364,8 @@ process_list_set(User, {value, Name}, Els) ->
|
||||
Error;
|
||||
{atomic, {result, _} = Res} ->
|
||||
ejabberd_router:route(
|
||||
{User, ?MYNAME, ""},
|
||||
{User, ?MYNAME, ""},
|
||||
jlib:make_jid(LUser, ?MYNAME, ""),
|
||||
jlib:make_jid(LUser, ?MYNAME, ""),
|
||||
{xmlelement, "broadcast", [],
|
||||
[{privacy_list, #userlist{name = Name, list = []}}]}),
|
||||
Res;
|
||||
@ -398,8 +393,8 @@ process_list_set(User, {value, Name}, Els) ->
|
||||
Error;
|
||||
{atomic, {result, _} = Res} ->
|
||||
ejabberd_router:route(
|
||||
{User, ?MYNAME, ""},
|
||||
{User, ?MYNAME, ""},
|
||||
jlib:make_jid(LUser, ?MYNAME, ""),
|
||||
jlib:make_jid(LUser, ?MYNAME, ""),
|
||||
{xmlelement, "broadcast", [],
|
||||
[{privacy_list, #userlist{name = Name, list = List}}]}),
|
||||
Res;
|
||||
@ -408,7 +403,7 @@ process_list_set(User, {value, Name}, Els) ->
|
||||
end
|
||||
end;
|
||||
|
||||
process_list_set(_User, false, _Els) ->
|
||||
process_list_set(_LUser, false, _Els) ->
|
||||
{error, ?ERR_BAD_REQUEST}.
|
||||
|
||||
|
||||
@ -523,7 +518,7 @@ parse_matches1(Item, [{xmlelement, _, _, _} | Els]) ->
|
||||
|
||||
|
||||
get_user_list(User) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
case catch mnesia:dirty_read(privacy, LUser) of
|
||||
[] ->
|
||||
#userlist{};
|
||||
|
@ -34,9 +34,7 @@ stop() ->
|
||||
|
||||
|
||||
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
{User, Server, _} = From,
|
||||
LUser = jlib:tolower(User),
|
||||
LServer = jlib:tolower(Server),
|
||||
#jid{luser = LUser, lserver = LServer} = From,
|
||||
case ?MYNAME of
|
||||
Server ->
|
||||
{xmlelement, Name, Attrs, Els} = SubEl,
|
||||
|
@ -47,14 +47,16 @@ start(Opts) ->
|
||||
proc_lib:spawn_link(?MODULE, init, [Host, ServedHosts, self()])).
|
||||
|
||||
|
||||
-define(MYJID, #jid{user = "", server = Host, resource = "",
|
||||
luser = "", lserver = Host, lresource = ""}).
|
||||
|
||||
init(Host, ServedHosts, Parent) ->
|
||||
ejabberd_router:register_route(Host),
|
||||
create_new_node(Host, ["pubsub"], {"", Host, ""}),
|
||||
create_new_node(Host, ["pubsub", "nodes"], {"", Host, ""}),
|
||||
create_new_node(Host, ["home"], {"", Host, ""}),
|
||||
create_new_node(Host, ["pubsub"], ?MYJID),
|
||||
create_new_node(Host, ["pubsub", "nodes"], ?MYJID),
|
||||
create_new_node(Host, ["home"], ?MYJID),
|
||||
lists:foreach(fun(H) ->
|
||||
create_new_node(Host, ["home", H], {"", Host, ""})
|
||||
create_new_node(Host, ["home", H], ?MYJID)
|
||||
end, ServedHosts),
|
||||
loop(Host, Parent).
|
||||
|
||||
@ -86,7 +88,7 @@ loop(Host, Parent) ->
|
||||
do_route(Host, From, To, Packet) ->
|
||||
{xmlelement, Name, Attrs, Els} = Packet,
|
||||
case To of
|
||||
{"", _, ""} ->
|
||||
#jid{luser = "", lresource = ""} ->
|
||||
case Name of
|
||||
"iq" ->
|
||||
case jlib:iq_query_info(Packet) of
|
||||
@ -115,9 +117,7 @@ do_route(Host, From, To, Packet) ->
|
||||
jlib:make_error_reply(
|
||||
Packet, Error)
|
||||
end,
|
||||
ejabberd_router:route(To,
|
||||
From,
|
||||
Res);
|
||||
ejabberd_router:route(To, From, Res);
|
||||
%{iq, ID, get, ?NS_REGISTER = XMLNS, SubEl} ->
|
||||
% Lang = xml:get_tag_attr_s(
|
||||
% "xml:lang", SubEl),
|
||||
@ -155,9 +155,7 @@ do_route(Host, From, To, Packet) ->
|
||||
jlib:make_error_reply(
|
||||
Packet, Error)
|
||||
end,
|
||||
ejabberd_router:route(To,
|
||||
From,
|
||||
Res);
|
||||
ejabberd_router:route(To, From, Res);
|
||||
{iq, ID, get, ?NS_VCARD = XMLNS, SubEl} ->
|
||||
Lang = xml:get_tag_attr_s(
|
||||
"xml:lang", SubEl),
|
||||
@ -982,10 +980,10 @@ subscription_to_string(Subscription) ->
|
||||
|
||||
check_create_permission(Host, Node, Owner) ->
|
||||
if
|
||||
{"", Host, ""} == Owner ->
|
||||
#jid{lserver = Host} == Owner ->
|
||||
true;
|
||||
true ->
|
||||
{User, Server, _} = Owner,
|
||||
#jid{luser = User, lserver = Server} = Owner,
|
||||
case Node of
|
||||
["home", Server, User | _] ->
|
||||
true;
|
||||
@ -1087,8 +1085,8 @@ broadcast_publish_item(Host, Node, ItemID, Payload) ->
|
||||
[{xmlelement, "item",
|
||||
ItemAttrs,
|
||||
Payload}]}]}]},
|
||||
ejabberd_router:route({"", Host, ""},
|
||||
JID, Stanza);
|
||||
ejabberd_router:route(
|
||||
?MYJID, jlib:make_jid(JID), Stanza);
|
||||
true ->
|
||||
ok
|
||||
end
|
||||
@ -1118,8 +1116,8 @@ broadcast_retract_item(Host, Node, ItemID) ->
|
||||
[{"node", node_to_string(Node)}],
|
||||
[{xmlelement, "retract",
|
||||
ItemAttrs, []}]}]}]},
|
||||
ejabberd_router:route({"", Host, ""},
|
||||
JID, Stanza);
|
||||
ejabberd_router:route(
|
||||
?MYJID, jlib:make_jid(JID), Stanza);
|
||||
true ->
|
||||
ok
|
||||
end
|
||||
@ -1144,8 +1142,8 @@ broadcast_removed_node(Host, Removed) ->
|
||||
[{xmlelement, "delete",
|
||||
[{"node", node_to_string(Node)}],
|
||||
[]}]}]},
|
||||
ejabberd_router:route({"", Host, ""},
|
||||
JID, Stanza);
|
||||
ejabberd_router:route(
|
||||
?MYJID, jlib:make_jid(JID), Stanza);
|
||||
true ->
|
||||
ok
|
||||
end
|
||||
|
@ -39,7 +39,7 @@ process_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
(UTag /= false) and (RTag /= false) ->
|
||||
User = xml:get_tag_cdata(UTag),
|
||||
case From of
|
||||
{User, Server, _} ->
|
||||
#jid{user = User, lserver = Server} ->
|
||||
ejabberd_auth:remove_user(User),
|
||||
{iq, ID, result, XMLNS, [SubEl]};
|
||||
_ ->
|
||||
@ -71,14 +71,18 @@ process_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
end
|
||||
end;
|
||||
(UTag == false) and (RTag /= false) ->
|
||||
{User, Server, _} = From,
|
||||
ejabberd_auth:remove_user(User),
|
||||
{iq, ID, result, XMLNS, [SubEl]};
|
||||
case From of
|
||||
#jid{user = User, lserver = Server} ->
|
||||
ejabberd_auth:remove_user(User),
|
||||
{iq, ID, result, XMLNS, [SubEl]};
|
||||
_ ->
|
||||
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}
|
||||
end;
|
||||
(UTag /= false) and (PTag /= false) ->
|
||||
User = xml:get_tag_cdata(UTag),
|
||||
Password = xml:get_tag_cdata(PTag),
|
||||
case From of
|
||||
{User, Server, _} ->
|
||||
#jid{user = User, lserver = Server} ->
|
||||
ejabberd_auth:set_password(User, Password),
|
||||
{iq, ID, result, XMLNS, [SubEl]};
|
||||
_ ->
|
||||
@ -117,7 +121,7 @@ try_register(User, Password) ->
|
||||
ok;
|
||||
{atomic, exists} ->
|
||||
% TODO: replace to "username unavailable"
|
||||
{error, ?ERR_BAD_REQUEST};
|
||||
{error, ?ERR_NOT_ALLOWED};
|
||||
{error, Reason} ->
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR}
|
||||
end
|
||||
|
@ -46,9 +46,9 @@ start(Opts) ->
|
||||
|
||||
process_iq(From, To, IQ) ->
|
||||
{iq, ID, Type, XMLNS, SubEl} = IQ,
|
||||
{_, Server, _} = From,
|
||||
#jid{lserver = LServer} = From,
|
||||
case ?MYNAME of
|
||||
Server ->
|
||||
LServer ->
|
||||
process_local_iq(From, To, IQ);
|
||||
_ ->
|
||||
{iq, ID, error, XMLNS,
|
||||
@ -67,8 +67,7 @@ process_local_iq(From, To, {iq, _, Type, _, _} = IQ) ->
|
||||
|
||||
|
||||
process_iq_get(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
{User, _, _} = From,
|
||||
LUser = jlib:tolower(User),
|
||||
#jid{luser = LUser} = From,
|
||||
F = fun() ->
|
||||
mnesia:index_read(roster, LUser, #roster.user)
|
||||
end,
|
||||
@ -120,19 +119,19 @@ item_to_xml(Item) ->
|
||||
|
||||
|
||||
process_iq_set(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
{User, _, _} = From,
|
||||
{xmlelement, Name, Attrs, Els} = SubEl,
|
||||
lists:foreach(fun(El) -> process_item_set(User, From, To, El) end, Els),
|
||||
lists:foreach(fun(El) -> process_item_set(From, To, El) end, Els),
|
||||
{iq, ID, result, XMLNS, []}.
|
||||
|
||||
process_item_set(User, From, To, {xmlelement, Name, Attrs, Els} = XItem) ->
|
||||
JID = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)),
|
||||
LUser = jlib:tolower(User),
|
||||
case JID of
|
||||
process_item_set(From, To, {xmlelement, Name, Attrs, Els} = XItem) ->
|
||||
JID1 = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)),
|
||||
#jid{user = User, luser = LUser} = From,
|
||||
case JID1 of
|
||||
error ->
|
||||
ok;
|
||||
_ ->
|
||||
LJID = jlib:jid_tolower(JID),
|
||||
JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource},
|
||||
LJID = jlib:jid_tolower(JID1),
|
||||
F = fun() ->
|
||||
Res = mnesia:read({roster, {LUser, LJID}}),
|
||||
Item = case Res of
|
||||
@ -175,7 +174,7 @@ process_item_set(User, From, To, {xmlelement, Name, Attrs, Els} = XItem) ->
|
||||
end,
|
||||
if IsTo ->
|
||||
ejabberd_router:route(
|
||||
From, OldItem#roster.jid,
|
||||
From, jlib:make_jid(OldItem#roster.jid),
|
||||
{xmlelement, "presence",
|
||||
[{"type", "unsubscribe"}],
|
||||
[]});
|
||||
@ -183,7 +182,7 @@ process_item_set(User, From, To, {xmlelement, Name, Attrs, Els} = XItem) ->
|
||||
end,
|
||||
if IsFrom ->
|
||||
ejabberd_router:route(
|
||||
From, OldItem#roster.jid,
|
||||
From, jlib:make_jid(OldItem#roster.jid),
|
||||
{xmlelement, "presence",
|
||||
[{"type", "unsubscribed"}],
|
||||
[]});
|
||||
@ -198,7 +197,7 @@ process_item_set(User, From, To, {xmlelement, Name, Attrs, Els} = XItem) ->
|
||||
ok
|
||||
end
|
||||
end;
|
||||
process_item_set(User, From, To, _) ->
|
||||
process_item_set(From, To, _) ->
|
||||
ok.
|
||||
|
||||
process_item_attrs(Item, [{Attr, Val} | Attrs]) ->
|
||||
@ -207,7 +206,8 @@ process_item_attrs(Item, [{Attr, Val} | Attrs]) ->
|
||||
case jlib:string_to_jid(Val) of
|
||||
error ->
|
||||
process_item_attrs(Item, Attrs);
|
||||
JID ->
|
||||
JID1 ->
|
||||
JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource},
|
||||
process_item_attrs(Item#roster{jid = JID}, Attrs)
|
||||
end;
|
||||
"name" ->
|
||||
@ -252,7 +252,9 @@ process_item_els(Item, []) ->
|
||||
|
||||
|
||||
push_item(User, From, Item) ->
|
||||
ejabberd_sm ! {route, {"", "", ""}, {User, "", ""},
|
||||
ejabberd_sm ! {route,
|
||||
jlib:make_jid("", "", ""),
|
||||
jlib:make_jid(User, "", ""),
|
||||
{xmlelement, "broadcast", [],
|
||||
[{item,
|
||||
Item#roster.jid,
|
||||
@ -269,12 +271,12 @@ push_item(User, Resource, From, Item) ->
|
||||
[item_to_xml(Item)]}]},
|
||||
ejabberd_router ! {route,
|
||||
From,
|
||||
{User, ?MYNAME, Resource},
|
||||
jlib:make_jid(User, ?MYNAME, Resource),
|
||||
jlib:iq_to_xml(ResIQ)}.
|
||||
|
||||
|
||||
get_subscription_lists(User) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
F = fun() ->
|
||||
mnesia:index_read(roster, LUser, #roster.user)
|
||||
end,
|
||||
@ -286,7 +288,6 @@ get_subscription_lists(User) ->
|
||||
end.
|
||||
|
||||
fill_subscription_lists([I | Is], F, T) ->
|
||||
%J = I#roster.jid,
|
||||
J = element(2, I#roster.uj),
|
||||
case I#roster.subscription of
|
||||
both ->
|
||||
@ -303,9 +304,8 @@ fill_subscription_lists([], F, T) ->
|
||||
|
||||
|
||||
in_subscription(User, From, Type) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
LFrom = jlib:jid_tolower(From),
|
||||
{FU, FS, FR} = From,
|
||||
F = fun() ->
|
||||
case mnesia:read({roster, {LUser, LFrom}}) of
|
||||
[] ->
|
||||
@ -317,6 +317,9 @@ in_subscription(User, From, Type) ->
|
||||
unsubscribed ->
|
||||
false;
|
||||
subscribed ->
|
||||
JID = {From#jid.user,
|
||||
From#jid.server,
|
||||
From#jid.resource},
|
||||
NewItem = #roster{uj = {LUser, LFrom},
|
||||
user = LUser,
|
||||
jid = From},
|
||||
@ -376,8 +379,12 @@ in_subscription(User, From, Type) ->
|
||||
{atomic, false} ->
|
||||
false;
|
||||
{atomic, {update, Presence, Item}} ->
|
||||
ejabberd_router:route({User, ?MYNAME, ""}, {FU, FS, ""}, Presence),
|
||||
ejabberd_sm ! {route, {"", "", ""}, {User, "", ""},
|
||||
ejabberd_router:route({User, ?MYNAME, ""},
|
||||
jlib:jid_replace_resource(From, ""),
|
||||
Presence),
|
||||
ejabberd_sm ! {route,
|
||||
jlib:make_jid("", "", ""),
|
||||
jlib:make_jid(User, "", ""),
|
||||
{xmlelement, "broadcast", [],
|
||||
[{item,
|
||||
Item#roster.jid,
|
||||
@ -390,9 +397,9 @@ in_subscription(User, From, Type) ->
|
||||
false
|
||||
end.
|
||||
|
||||
out_subscription(User, JID, Type) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LJID = jlib:jid_tolower(JID),
|
||||
out_subscription(User, JID1, Type) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LJID = jlib:jid_tolower(JID1),
|
||||
F = fun() ->
|
||||
Item = case mnesia:read({roster, {LUser, LJID}}) of
|
||||
[] ->
|
||||
@ -400,6 +407,9 @@ out_subscription(User, JID, Type) ->
|
||||
(Type == unsubscribed) ->
|
||||
false;
|
||||
true ->
|
||||
JID = {JID1#jid.user,
|
||||
JID1#jid.server,
|
||||
JID1#jid.resource},
|
||||
#roster{uj = {LUser, LJID},
|
||||
user = LUser,
|
||||
jid = JID}
|
||||
@ -448,7 +458,9 @@ out_subscription(User, JID, Type) ->
|
||||
push_item(User, {"", ?MYNAME, ""}, Item),
|
||||
if
|
||||
Update ->
|
||||
ejabberd_sm ! {route, {"", "", ""}, {User, "", ""},
|
||||
ejabberd_sm ! {route,
|
||||
jlib:make_jid("", "", ""),
|
||||
jlib:make_jid(User, "", ""),
|
||||
{xmlelement, "broadcast", [],
|
||||
[{item,
|
||||
Item#roster.jid,
|
||||
@ -461,7 +473,7 @@ out_subscription(User, JID, Type) ->
|
||||
end.
|
||||
|
||||
remove_user(User) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
F = fun() ->
|
||||
lists:foreach(fun(R) ->
|
||||
mnesia:delete_object(R)
|
||||
@ -480,12 +492,13 @@ set_items(User, SubEl) ->
|
||||
mnesia:transaction(F).
|
||||
|
||||
process_item_set_t(User, {xmlelement, Name, Attrs, Els} = XItem) ->
|
||||
JID = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)),
|
||||
LUser = jlib:tolower(User),
|
||||
case JID of
|
||||
JID1 = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)),
|
||||
LUser = jlib:nodeprep(User),
|
||||
case JID1 of
|
||||
error ->
|
||||
ok;
|
||||
_ ->
|
||||
JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource},
|
||||
LJID = jlib:jid_tolower(JID),
|
||||
Res = mnesia:read({roster, {LUser, LJID}}),
|
||||
Item = #roster{uj = {LUser, LJID},
|
||||
@ -509,7 +522,8 @@ process_item_attrs_ws(Item, [{Attr, Val} | Attrs]) ->
|
||||
case jlib:string_to_jid(Val) of
|
||||
error ->
|
||||
process_item_attrs_ws(Item, Attrs);
|
||||
JID ->
|
||||
JID1 ->
|
||||
JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource},
|
||||
process_item_attrs_ws(Item#roster{jid = JID}, Attrs)
|
||||
end;
|
||||
"name" ->
|
||||
@ -548,7 +562,7 @@ process_item_attrs_ws(Item, []) ->
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
get_jid_info(User, JID) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
LJID = jlib:jid_tolower(JID),
|
||||
case catch mnesia:dirty_read(roster, {LUser, LJID}) of
|
||||
[#roster{subscription = Subscription, groups = Groups}] ->
|
||||
|
@ -72,7 +72,12 @@ init(Host) ->
|
||||
loop() ->
|
||||
receive
|
||||
{route, From, To, Packet} ->
|
||||
do_route(From, To, Packet),
|
||||
case catch do_route(From, To, Packet) of
|
||||
{'EXIT', Reason} ->
|
||||
?ERROR_MSG("~p", [Reason]);
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
loop();
|
||||
_ ->
|
||||
loop()
|
||||
@ -104,9 +109,7 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
case Type of
|
||||
set ->
|
||||
{User, Server, _} = From,
|
||||
LUser = jlib:tolower(User),
|
||||
LServer = jlib:tolower(Server),
|
||||
#jid{user = User, lserver = LServer, luser = LUser} = From,
|
||||
case ?MYNAME of
|
||||
LServer ->
|
||||
set_vcard(User, SubEl),
|
||||
@ -116,8 +119,7 @@ process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
[SubEl, ?ERR_NOT_ALLOWED]}
|
||||
end;
|
||||
get ->
|
||||
{User, _, _} = To,
|
||||
LUser = jlib:tolower(User),
|
||||
#jid{luser = LUser} = To,
|
||||
F = fun() ->
|
||||
mnesia:read({vcard, LUser})
|
||||
end,
|
||||
@ -145,18 +147,18 @@ set_vcard(User, VCARD) ->
|
||||
OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]),
|
||||
OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]),
|
||||
|
||||
LUser = jlib:tolower(User),
|
||||
LFN = jlib:tolower(FN),
|
||||
LFamily = jlib:tolower(Family),
|
||||
LGiven = jlib:tolower(Given),
|
||||
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),
|
||||
LUser = jlib:nodeprep(User),
|
||||
LFN = stringprep:tolower(FN),
|
||||
LFamily = stringprep:tolower(Family),
|
||||
LGiven = stringprep:tolower(Given),
|
||||
LMiddle = stringprep:tolower(Middle),
|
||||
LNickname = stringprep:tolower(Nickname),
|
||||
LBDay = stringprep:tolower(BDay),
|
||||
LCTRY = stringprep:tolower(CTRY),
|
||||
LLocality = stringprep:tolower(Locality),
|
||||
LEMail = stringprep:tolower(EMail),
|
||||
LOrgName = stringprep:tolower(OrgName),
|
||||
LOrgUnit = stringprep:tolower(OrgUnit),
|
||||
|
||||
F = fun() ->
|
||||
mnesia:write(#vcard{user = LUser, vcard = VCARD}),
|
||||
@ -210,7 +212,7 @@ set_vcard(User, VCARD) ->
|
||||
|
||||
|
||||
do_route(From, To, Packet) ->
|
||||
{User, Server, Resource} = To,
|
||||
#jid{user = User, resource = Resource} = To,
|
||||
if
|
||||
(User /= "") or (Resource /= "") ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE),
|
||||
@ -400,7 +402,7 @@ filter_fields([], Match) ->
|
||||
Match;
|
||||
filter_fields([{SVar, [Val]} | Ds], Match)
|
||||
when is_list(Val) and (Val /= "") ->
|
||||
LVal = jlib:tolower(Val),
|
||||
LVal = stringprep:tolower(Val),
|
||||
NewMatch = case SVar of
|
||||
"user" -> Match#vcard_search{luser = LVal};
|
||||
"fn" -> Match#vcard_search{lfn = LVal};
|
||||
@ -439,18 +441,18 @@ set_vcard_t(R, _) ->
|
||||
OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]),
|
||||
OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]),
|
||||
|
||||
LUser = jlib:tolower(User),
|
||||
LFN = jlib:tolower(FN),
|
||||
LFamily = jlib:tolower(Family),
|
||||
LGiven = jlib:tolower(Given),
|
||||
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),
|
||||
LUser = jlib:nodeprep(User),
|
||||
LFN = stringprep:tolower(FN),
|
||||
LFamily = stringprep:tolower(Family),
|
||||
LGiven = stringprep:tolower(Given),
|
||||
LMiddle = stringprep:tolower(Middle),
|
||||
LNickname = stringprep:tolower(Nickname),
|
||||
LBDay = stringprep:tolower(BDay),
|
||||
LCTRY = stringprep:tolower(CTRY),
|
||||
LLocality = stringprep:tolower(Locality),
|
||||
LEMail = stringprep:tolower(EMail),
|
||||
LOrgName = stringprep:tolower(OrgName),
|
||||
LOrgUnit = stringprep:tolower(OrgUnit),
|
||||
|
||||
mnesia:write(
|
||||
#vcard_search{user = User, luser = LUser,
|
||||
@ -476,7 +478,7 @@ reindex_vcards() ->
|
||||
|
||||
|
||||
remove_user(User) ->
|
||||
LUser = jlib:tolower(User),
|
||||
LUser = jlib:nodeprep(User),
|
||||
F = fun() ->
|
||||
mnesia:delete({vcard, LUser}),
|
||||
lists:foreach(fun(R) ->
|
||||
|
@ -32,8 +32,38 @@ static void stringprep_erl_stop(ErlDrvData handle)
|
||||
driver_free((char*)handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* "canonical_ordering" and "compose" functions are based on nfkc.c from Gnome
|
||||
* library
|
||||
*/
|
||||
|
||||
static int combine(int ch1, int ch2)
|
||||
void canonical_ordering(int *str, int len)
|
||||
{
|
||||
int i, j, t;
|
||||
int last, next;
|
||||
|
||||
last = GetUniCharCClass(str[0]);
|
||||
for (i = 0; i < len - 1; i++)
|
||||
{
|
||||
next = GetUniCharCClass(str[i + 1]);
|
||||
if (next != 0 && last > next)
|
||||
{
|
||||
for(j = i; j > 0; j--)
|
||||
{
|
||||
if (GetUniCharCClass(str[j]) <= next)
|
||||
break;
|
||||
t = str[j + 1];
|
||||
str[j + 1] = str[j];
|
||||
str[j] = t;
|
||||
}
|
||||
next = last;
|
||||
}
|
||||
last = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int compose(int ch1, int ch2)
|
||||
{
|
||||
int info1, info2;
|
||||
|
||||
@ -90,6 +120,29 @@ static int combine(int ch1, int ch2)
|
||||
pos += 3; \
|
||||
}
|
||||
|
||||
#define ADD_UCHAR32(str, pos, len, ch) \
|
||||
if(pos >= len) { \
|
||||
len = 2*len + 1; \
|
||||
str = driver_realloc(str, len * sizeof(int)); \
|
||||
} \
|
||||
str[pos] = ch; \
|
||||
pos++;
|
||||
|
||||
|
||||
#define ADD_DECOMP(ruc) \
|
||||
info = GetUniCharDecompInfo(ruc); \
|
||||
if(info >= 0) { \
|
||||
decomp_len = GetDecompLen(info); \
|
||||
decomp_shift = GetDecompShift(info); \
|
||||
for(j = 0; j < decomp_len; j++) { \
|
||||
ADD_UCHAR32(str32, str32pos, str32len, \
|
||||
decompList[decomp_shift + j]); \
|
||||
} \
|
||||
} else { \
|
||||
ADD_UCHAR32(str32, str32pos, str32len, ruc); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int stringprep_erl_control(ErlDrvData drv_data,
|
||||
unsigned int command,
|
||||
@ -105,12 +158,22 @@ static int stringprep_erl_control(ErlDrvData drv_data,
|
||||
int prohibit, tolower;
|
||||
char *rstring;
|
||||
int *mc;
|
||||
int *str32;
|
||||
int str32len, str32pos = 0;
|
||||
int decomp_len, decomp_shift;
|
||||
int comp_pos;
|
||||
int cclass1, cclass2;
|
||||
int ch1, ch2;
|
||||
|
||||
size = len + 1;
|
||||
|
||||
rstring = driver_alloc(size);
|
||||
rstring[0] = 0;
|
||||
|
||||
str32len = len + 1;
|
||||
|
||||
str32 = driver_alloc(str32len * sizeof(int));
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case 0:
|
||||
@ -134,7 +197,7 @@ static int stringprep_erl_control(ErlDrvData drv_data,
|
||||
break;
|
||||
}
|
||||
|
||||
for(i=0; i < len; i++)
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
c = buf[i];
|
||||
if(c < 0x80) {
|
||||
@ -164,12 +227,14 @@ static int stringprep_erl_control(ErlDrvData drv_data,
|
||||
|
||||
if(bad) {
|
||||
*rbuf = rstring;
|
||||
driver_free(str32);
|
||||
return 1;
|
||||
}
|
||||
|
||||
info = GetUniCharInfo(uc);
|
||||
if(info & prohibit) {
|
||||
*rbuf = rstring;
|
||||
driver_free(str32);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -180,6 +245,19 @@ static int stringprep_erl_control(ErlDrvData drv_data,
|
||||
if(!(info & MCMask))
|
||||
{
|
||||
ruc = uc + GetDelta(info);
|
||||
ADD_DECOMP(ruc);
|
||||
|
||||
//info = GetUniCharDecompInfo(ruc);
|
||||
//if(info >= 0) {
|
||||
// decomp_len = GetDecompLen(info);
|
||||
// decomp_shift = GetDecompShift(info);
|
||||
// for(j = 0; j < decomp_len; j++) {
|
||||
// ADD_UCHAR32(str32, str32pos, str32len,
|
||||
// decompList[decomp_shift + j]);
|
||||
// }
|
||||
//} else {
|
||||
// ADD_UCHAR32(str32, str32pos, str32len, ruc);
|
||||
//}
|
||||
|
||||
//info = GetUniCharDecompInfo(ruc);
|
||||
//if(info >= 0) {
|
||||
@ -190,26 +268,63 @@ static int stringprep_erl_control(ErlDrvData drv_data,
|
||||
// printf("\r\n");
|
||||
//}
|
||||
|
||||
ADD_UCHAR(ruc);
|
||||
//ADD_UCHAR(ruc);
|
||||
} else {
|
||||
mc = GetMC(info);
|
||||
for(j = 1; j <= mc[0]; j++) {
|
||||
ruc = mc[j];
|
||||
//printf("Char %x cclass %d\r\n", ruc, GetUniCharCClass(ruc));
|
||||
ADD_UCHAR(ruc);
|
||||
ADD_DECOMP(ruc);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ruc = uc;
|
||||
ADD_UCHAR(ruc);
|
||||
ADD_DECOMP(ruc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//printf("Combine: %x\r\n", combine(0x438, 0x301));
|
||||
if (str32pos == 0) {
|
||||
rstring[0] = 1;
|
||||
*rbuf = rstring;
|
||||
driver_free(str32);
|
||||
return 1;
|
||||
}
|
||||
|
||||
canonical_ordering(str32, str32pos);
|
||||
|
||||
comp_pos = 0;
|
||||
ch1 = str32[0];
|
||||
cclass1 = GetUniCharCClass(ch1);
|
||||
for(i = 1; i < str32pos; i++)
|
||||
{
|
||||
ch2 = str32[i];
|
||||
cclass2 = GetUniCharCClass(ch2);
|
||||
//printf("Compose: %x + %x = %x\r\n", ch1, ch2, compose(ch1, ch2));
|
||||
if(cclass1 == 0 && cclass1 < cclass2 && (ruc = compose(ch1, ch2))) {
|
||||
ch1 = ruc;
|
||||
} else {
|
||||
str32[comp_pos] = ch1;
|
||||
comp_pos++;
|
||||
ch1 = ch2;
|
||||
}
|
||||
}
|
||||
str32[comp_pos] = ch1;
|
||||
str32pos = comp_pos+1;
|
||||
|
||||
|
||||
for(i = 0; i < str32pos; i++)
|
||||
{
|
||||
ruc = str32[i];
|
||||
ADD_UCHAR(ruc);
|
||||
}
|
||||
|
||||
//printf("Compose: %x\r\n", compose(0x438, 0x301));
|
||||
//printf("Pos: %d\r\n", pos);
|
||||
|
||||
rstring[0] = 1;
|
||||
*rbuf = rstring;
|
||||
driver_free(str32);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -283,6 +283,12 @@ proc uni::buildTables {} {
|
||||
|
||||
if {[info exists decomp_map($i)]} {
|
||||
set decomp $decomp_map($i)
|
||||
#puts -$decomp
|
||||
while {[info exists decomp_map([set ch1 [lindex $decomp 0]])]} {
|
||||
set decomp [concat $decomp_map($ch1) [lreplace $decomp 0 0]]
|
||||
#puts +$decomp
|
||||
}
|
||||
|
||||
if {[info exists decomp_used($decomp)]} {
|
||||
lappend decomp_info $decomp_used($decomp)
|
||||
} else {
|
||||
@ -442,75 +448,6 @@ static unsigned char cclassGroupMap\[\] = {"
|
||||
puts $f $line
|
||||
puts $f "};
|
||||
|
||||
/*
|
||||
* Each group represents a unique set of character attributes. The attributes
|
||||
* are encoded into a 32-bit value as follows:
|
||||
*
|
||||
* Bits 0-4 Character category: see the constants listed below.
|
||||
*
|
||||
* Bits 5-7 Case delta type: 000 = identity
|
||||
* 010 = add delta for lower
|
||||
* 011 = add delta for lower, add 1 for title
|
||||
* 100 = sutract delta for title/upper
|
||||
* 101 = sub delta for upper, sub 1 for title
|
||||
* 110 = sub delta for upper, add delta for lower
|
||||
*
|
||||
* Bits 8-21 Reserved for future use.
|
||||
*
|
||||
* Bits 22-31 Case delta: delta for case conversions. This should be the
|
||||
* highest field so we can easily sign extend.
|
||||
*/
|
||||
|
||||
static int cclass_groups\[\] = {"
|
||||
set line " "
|
||||
set last [expr {[llength $groups] - 1}]
|
||||
for {set i 0} {$i <= $last} {incr i} {
|
||||
foreach {type toupper tolower totitle} [split [lindex $groups $i] ,] {}
|
||||
|
||||
# Compute the case conversion type and delta
|
||||
|
||||
if {$totitle != ""} {
|
||||
if {$totitle == $toupper} {
|
||||
# subtract delta for title or upper
|
||||
set case 4
|
||||
set delta $toupper
|
||||
} elseif {$toupper != ""} {
|
||||
# subtract delta for upper, subtract 1 for title
|
||||
set case 5
|
||||
set delta $toupper
|
||||
} else {
|
||||
# add delta for lower, add 1 for title
|
||||
set case 3
|
||||
set delta $tolower
|
||||
}
|
||||
} elseif {$toupper != ""} {
|
||||
# subtract delta for upper, add delta for lower
|
||||
set case 6
|
||||
set delta $toupper
|
||||
} elseif {$tolower != ""} {
|
||||
# add delta for lower
|
||||
set case 2
|
||||
set delta $tolower
|
||||
} else {
|
||||
# noop
|
||||
set case 0
|
||||
set delta 0
|
||||
}
|
||||
|
||||
set val [expr {($delta << 22) | ($case << 5) | $type}]
|
||||
|
||||
append line [format "%d" $val]
|
||||
if {$i != $last} {
|
||||
append line ", "
|
||||
}
|
||||
if {[string length $line] > 65} {
|
||||
puts $f $line
|
||||
set line " "
|
||||
}
|
||||
}
|
||||
puts $f $line
|
||||
puts $f "};
|
||||
|
||||
#define GetUniCharCClass(ch) (cclassGroupMap\[(cclassPageMap\[(((int)(ch)) & 0xffff) >> CCLASS_OFFSET_BITS\] << CCLASS_OFFSET_BITS) | ((ch) & ((1 << CCLASS_OFFSET_BITS)-1))\])
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user