mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
In mod_offline:
o Remove any compatibility code: the core of Ejabberd expects new structures. o Add table conversion. o Add try/catch block around exmpp_stringprep:*prep/1 uses. To permit the complete removal of the compatibility code, jlib had to be changed too: the timestamp_to_xml/1 function now returns an #xmlel. SVN Revision: 1575
This commit is contained in:
parent
c74ab439ef
commit
c068d20588
@ -1,3 +1,12 @@
|
|||||||
|
2008-09-25 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||||
|
|
||||||
|
* src/jlib.erl (timestamp_to_xml): Create an #xmlel element, not an
|
||||||
|
old #xmlelement.
|
||||||
|
|
||||||
|
* src/mod_offline.erl: Remove any compatibility code: the core of
|
||||||
|
Ejabberd expects new structures. Add table conversion. Add try/catch
|
||||||
|
block around exmpp_stringprep:*prep/1 uses.
|
||||||
|
|
||||||
2008-09-23 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
2008-09-23 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||||
|
|
||||||
* src/mod_vcard.erl (process_sm_iq): Fix a bug where a badmatch
|
* src/mod_vcard.erl (process_sm_iq): Fix a bug where a badmatch
|
||||||
|
13
src/jlib.erl
13
src/jlib.erl
@ -68,6 +68,8 @@
|
|||||||
short_prepd_jid/1,
|
short_prepd_jid/1,
|
||||||
short_prepd_bare_jid/1]).
|
short_prepd_bare_jid/1]).
|
||||||
|
|
||||||
|
-include_lib("exmpp/include/exmpp_xml.hrl").
|
||||||
|
|
||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
|
|
||||||
%send_iq(From, To, ID, SubTags) ->
|
%send_iq(From, To, ID, SubTags) ->
|
||||||
@ -517,12 +519,11 @@ timestamp_to_iso({{Year, Month, Day}, {Hour, Minute, Second}}) ->
|
|||||||
[Year, Month, Day, Hour, Minute, Second])).
|
[Year, Month, Day, Hour, Minute, Second])).
|
||||||
|
|
||||||
timestamp_to_xml({{Year, Month, Day}, {Hour, Minute, Second}}) ->
|
timestamp_to_xml({{Year, Month, Day}, {Hour, Minute, Second}}) ->
|
||||||
{xmlelement, "x",
|
Timestamp = lists:flatten(
|
||||||
[{"xmlns", ?NS_DELAY},
|
io_lib:format("~4..0w~2..0w~2..0wT~2..0w:~2..0w:~2..0w",
|
||||||
{"stamp", lists:flatten(
|
[Year, Month, Day, Hour, Minute, Second])),
|
||||||
io_lib:format("~4..0w~2..0w~2..0wT~2..0w:~2..0w:~2..0w",
|
exmpp_xml:set_attribute(#xmlel{ns = ?NS_DELAY, name = 'x'},
|
||||||
[Year, Month, Day, Hour, Minute, Second]))}],
|
'stamp', Timestamp).
|
||||||
[]}.
|
|
||||||
|
|
||||||
now_to_utc_string({MegaSecs, Secs, MicroSecs}) ->
|
now_to_utc_string({MegaSecs, Secs, MicroSecs}) ->
|
||||||
{{Year, Month, Day}, {Hour, Minute, Second}} =
|
{{Year, Month, Day}, {Hour, Minute, Second}} =
|
||||||
|
@ -157,16 +157,13 @@ store_packet(From, To, Packet) ->
|
|||||||
#jid{lnode = LUser, ldomain = LServer} = To,
|
#jid{lnode = LUser, ldomain = LServer} = To,
|
||||||
TimeStamp = now(),
|
TimeStamp = now(),
|
||||||
Expire = find_x_expire(TimeStamp, Packet#xmlel.children),
|
Expire = find_x_expire(TimeStamp, Packet#xmlel.children),
|
||||||
% XXX OLD FORMAT: Packet is stored in the old format.
|
|
||||||
PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
|
|
||||||
[?DEFAULT_NS], ?PREFIXED_NS),
|
|
||||||
gen_mod:get_module_proc(To#jid.ldomain, ?PROCNAME) !
|
gen_mod:get_module_proc(To#jid.ldomain, ?PROCNAME) !
|
||||||
#offline_msg{us = {LUser, LServer},
|
#offline_msg{us = {LUser, LServer},
|
||||||
timestamp = TimeStamp,
|
timestamp = TimeStamp,
|
||||||
expire = Expire,
|
expire = Expire,
|
||||||
from = From,
|
from = From,
|
||||||
to = To,
|
to = To,
|
||||||
packet = PacketOld},
|
packet = Packet},
|
||||||
stop;
|
stop;
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
@ -233,80 +230,76 @@ find_x_expire(TimeStamp, [_ | Els]) ->
|
|||||||
|
|
||||||
|
|
||||||
resend_offline_messages(User, Server) ->
|
resend_offline_messages(User, Server) ->
|
||||||
LUser = exmpp_stringprep:nodeprep(User),
|
try
|
||||||
LServer = exmpp_stringprep:nameprep(Server),
|
LUser = exmpp_stringprep:nodeprep(User),
|
||||||
US = {LUser, LServer},
|
LServer = exmpp_stringprep:nameprep(Server),
|
||||||
F = fun() ->
|
US = {LUser, LServer},
|
||||||
Rs = mnesia:wread({offline_msg, US}),
|
F = fun() ->
|
||||||
mnesia:delete({offline_msg, US}),
|
Rs = mnesia:wread({offline_msg, US}),
|
||||||
Rs
|
mnesia:delete({offline_msg, US}),
|
||||||
end,
|
Rs
|
||||||
case mnesia:transaction(F) of
|
end,
|
||||||
{atomic, Rs} ->
|
case mnesia:transaction(F) of
|
||||||
lists:foreach(
|
{atomic, Rs} ->
|
||||||
fun(R) ->
|
lists:foreach(
|
||||||
Packet = case R#offline_msg.packet of
|
fun(R) ->
|
||||||
#xmlelement{} = P ->
|
Packet = R#offline_msg.packet,
|
||||||
exmpp_xml:xmlelement_to_xmlel(P,
|
ejabberd_sm !
|
||||||
[?DEFAULT_NS], ?PREFIXED_NS);
|
{route,
|
||||||
#xmlel{} = P ->
|
R#offline_msg.from,
|
||||||
P
|
R#offline_msg.to,
|
||||||
end,
|
exmpp_xml:append_child(Packet,
|
||||||
% XXX OLD FORMAT: Convert From & To.
|
jlib:timestamp_to_xml(
|
||||||
ejabberd_sm !
|
calendar:now_to_universal_time(
|
||||||
{route,
|
R#offline_msg.timestamp)))}
|
||||||
jlib:from_old_jid(R#offline_msg.from),
|
end,
|
||||||
jlib:from_old_jid(R#offline_msg.to),
|
lists:keysort(#offline_msg.timestamp, Rs));
|
||||||
exmpp_xml:append_child(Packet,
|
_ ->
|
||||||
jlib:timestamp_to_xml(
|
ok
|
||||||
calendar:now_to_universal_time(
|
end
|
||||||
R#offline_msg.timestamp)))}
|
catch
|
||||||
end,
|
|
||||||
lists:keysort(#offline_msg.timestamp, Rs));
|
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
pop_offline_messages(Ls, User, Server) ->
|
pop_offline_messages(Ls, User, Server) ->
|
||||||
LUser = exmpp_stringprep:nodeprep(User),
|
try
|
||||||
LServer = exmpp_stringprep:nameprep(Server),
|
LUser = exmpp_stringprep:nodeprep(User),
|
||||||
US = {LUser, LServer},
|
LServer = exmpp_stringprep:nameprep(Server),
|
||||||
F = fun() ->
|
US = {LUser, LServer},
|
||||||
Rs = mnesia:wread({offline_msg, US}),
|
F = fun() ->
|
||||||
mnesia:delete({offline_msg, US}),
|
Rs = mnesia:wread({offline_msg, US}),
|
||||||
Rs
|
mnesia:delete({offline_msg, US}),
|
||||||
end,
|
Rs
|
||||||
case mnesia:transaction(F) of
|
end,
|
||||||
{atomic, Rs} ->
|
case mnesia:transaction(F) of
|
||||||
TS = now(),
|
{atomic, Rs} ->
|
||||||
Ls ++ lists:map(
|
TS = now(),
|
||||||
fun(R) ->
|
Ls ++ lists:map(
|
||||||
Packet = case R#offline_msg.packet of
|
fun(R) ->
|
||||||
#xmlelement{} = P ->
|
Packet = R#offline_msg.packet,
|
||||||
exmpp_xml:xmlelement_to_xmlel(P,
|
{route,
|
||||||
[?DEFAULT_NS], ?PREFIXED_NS);
|
R#offline_msg.from,
|
||||||
#xmlel{} = P ->
|
R#offline_msg.to,
|
||||||
P
|
exmpp_xml:append_child(Packet,
|
||||||
end,
|
jlib:timestamp_to_xml(
|
||||||
% XXX OLD FORMAT: Convert From & To.
|
calendar:now_to_universal_time(
|
||||||
{route,
|
R#offline_msg.timestamp)))}
|
||||||
jlib:from_old_jid(R#offline_msg.from),
|
end,
|
||||||
jlib:from_old_jid(R#offline_msg.to),
|
lists:filter(
|
||||||
exmpp_xml:append_child(Packet,
|
fun(R) ->
|
||||||
jlib:timestamp_to_xml(
|
case R#offline_msg.expire of
|
||||||
calendar:now_to_universal_time(
|
never ->
|
||||||
R#offline_msg.timestamp)))}
|
true;
|
||||||
end,
|
TimeStamp ->
|
||||||
lists:filter(
|
TS < TimeStamp
|
||||||
fun(R) ->
|
end
|
||||||
case R#offline_msg.expire of
|
end,
|
||||||
never ->
|
lists:keysort(#offline_msg.timestamp, Rs)));
|
||||||
true;
|
_ ->
|
||||||
TimeStamp ->
|
Ls
|
||||||
TS < TimeStamp
|
end
|
||||||
end
|
catch
|
||||||
end,
|
|
||||||
lists:keysort(#offline_msg.timestamp, Rs)));
|
|
||||||
_ ->
|
_ ->
|
||||||
Ls
|
Ls
|
||||||
end.
|
end.
|
||||||
@ -350,19 +343,24 @@ remove_old_messages(Days) ->
|
|||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
remove_user(User, Server) ->
|
remove_user(User, Server) ->
|
||||||
LUser = exmpp_stringprep:nodeprep(User),
|
try
|
||||||
LServer = exmpp_stringprep:nameprep(Server),
|
LUser = exmpp_stringprep:nodeprep(User),
|
||||||
US = {LUser, LServer},
|
LServer = exmpp_stringprep:nameprep(Server),
|
||||||
F = fun() ->
|
US = {LUser, LServer},
|
||||||
mnesia:delete({offline_msg, US})
|
F = fun() ->
|
||||||
end,
|
mnesia:delete({offline_msg, US})
|
||||||
mnesia:transaction(F).
|
end,
|
||||||
|
mnesia:transaction(F)
|
||||||
|
catch
|
||||||
|
_ ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
update_table() ->
|
update_table() ->
|
||||||
Fields = record_info(fields, offline_msg),
|
Fields = record_info(fields, offline_msg),
|
||||||
case mnesia:table_info(offline_msg, attributes) of
|
case mnesia:table_info(offline_msg, attributes) of
|
||||||
Fields ->
|
Fields ->
|
||||||
ok;
|
convert_to_exmpp();
|
||||||
[user, timestamp, expire, from, to, packet] ->
|
[user, timestamp, expire, from, to, packet] ->
|
||||||
?INFO_MSG("Converting offline_msg table from "
|
?INFO_MSG("Converting offline_msg table from "
|
||||||
"{user, timestamp, expire, from, to, packet} format", []),
|
"{user, timestamp, expire, from, to, packet} format", []),
|
||||||
@ -378,11 +376,19 @@ update_table() ->
|
|||||||
F1 = fun() ->
|
F1 = fun() ->
|
||||||
mnesia:write_lock_table(mod_offline_tmp_table),
|
mnesia:write_lock_table(mod_offline_tmp_table),
|
||||||
mnesia:foldl(
|
mnesia:foldl(
|
||||||
fun(#offline_msg{us = U, packet = P} = R, _) ->
|
fun(#offline_msg{us = U, from = F, to = T, packet = P} = R, _) ->
|
||||||
|
U1 = convert_jid_to_exmpp(U),
|
||||||
|
F1 = jlib:from_old_jid(F),
|
||||||
|
T1 = jlib:from_old_jid(T),
|
||||||
|
P1 = exmpp_xml:xmlelement_to_xmlel(
|
||||||
|
P,
|
||||||
|
[?DEFAULT_NS],
|
||||||
|
?PREFIXED_NS),
|
||||||
New_R = R#offline_msg{
|
New_R = R#offline_msg{
|
||||||
us = {U, Host},
|
us = {U1, Host},
|
||||||
packet = exmpp_xml:xmlelement_to_xmlel(P,
|
from = F1,
|
||||||
[?DEFAULT_NS], ?PREFIXED_NS)
|
to = T1,
|
||||||
|
packet = P1
|
||||||
},
|
},
|
||||||
mnesia:dirty_write(
|
mnesia:dirty_write(
|
||||||
mod_offline_tmp_table,
|
mod_offline_tmp_table,
|
||||||
@ -415,12 +421,19 @@ update_table() ->
|
|||||||
offline_msg,
|
offline_msg,
|
||||||
fun({_, U, TS, F, T, P}) ->
|
fun({_, U, TS, F, T, P}) ->
|
||||||
Expire = find_x_expire(TS, P#xmlelement.children),
|
Expire = find_x_expire(TS, P#xmlelement.children),
|
||||||
#offline_msg{us = U,
|
U1 = convert_jid_to_exmpp(U),
|
||||||
|
F1 = jlib:from_old_jid(F),
|
||||||
|
T1 = jlib:from_old_jid(T),
|
||||||
|
P1 = exmpp_xml:xmlelement_to_xmlel(
|
||||||
|
P,
|
||||||
|
[?DEFAULT_NS],
|
||||||
|
?PREFIXED_NS),
|
||||||
|
#offline_msg{us = U1,
|
||||||
timestamp = TS,
|
timestamp = TS,
|
||||||
expire = Expire,
|
expire = Expire,
|
||||||
from = F,
|
from = F1,
|
||||||
to = T,
|
to = T1,
|
||||||
packet = P}
|
packet = P1}
|
||||||
end, Fields),
|
end, Fields),
|
||||||
F1 = fun() ->
|
F1 = fun() ->
|
||||||
mnesia:write_lock_table(mod_offline_tmp_table),
|
mnesia:write_lock_table(mod_offline_tmp_table),
|
||||||
@ -447,27 +460,64 @@ update_table() ->
|
|||||||
mnesia:transform_table(offline_msg, ignore, Fields)
|
mnesia:transform_table(offline_msg, ignore, Fields)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
convert_to_exmpp() ->
|
||||||
|
Fun = fun() ->
|
||||||
|
case mnesia:first(offline_msg) of
|
||||||
|
'$end_of_table' ->
|
||||||
|
none;
|
||||||
|
Key ->
|
||||||
|
case mnesia:read({offline_msg, Key}) of
|
||||||
|
[#offline_msg{packet = #xmlel{}} | _] ->
|
||||||
|
none;
|
||||||
|
[#offline_msg{packet = #xmlelement{}} | _] ->
|
||||||
|
mnesia:foldl(fun convert_to_exmpp2/2,
|
||||||
|
done, offline_msg, write)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
mnesia:transaction(Fun).
|
||||||
|
|
||||||
|
convert_to_exmpp2(#offline_msg{
|
||||||
|
us = {US_U, US_S},
|
||||||
|
from = From,
|
||||||
|
to = To,
|
||||||
|
packet = Packet} = R, Acc) ->
|
||||||
|
% Remove old entry.
|
||||||
|
mnesia:delete_object(R),
|
||||||
|
% Convert "" to undefined in JIDs.
|
||||||
|
US_U1 = convert_jid_to_exmpp(US_U),
|
||||||
|
US_S1 = convert_jid_to_exmpp(US_S),
|
||||||
|
From1 = jlib:from_old_jid(From),
|
||||||
|
To1 = jlib:from_old_jid(To),
|
||||||
|
% Convert stanza.
|
||||||
|
Packet1 = exmpp_xml:xmlelement_to_xmlel(Packet,
|
||||||
|
[?DEFAULT_NS], ?PREFIXED_NS),
|
||||||
|
% Prepare the new record.
|
||||||
|
New_R = R#offline_msg{
|
||||||
|
us = {US_U1, US_S1},
|
||||||
|
from = From1,
|
||||||
|
to = To1,
|
||||||
|
packet = Packet1},
|
||||||
|
% Write the new record.
|
||||||
|
mnesia:write(New_R),
|
||||||
|
Acc.
|
||||||
|
|
||||||
|
convert_jid_to_exmpp("") -> undefined;
|
||||||
|
convert_jid_to_exmpp(V) -> V.
|
||||||
|
|
||||||
%% Helper functions:
|
%% Helper functions:
|
||||||
|
|
||||||
%% Warn senders that their messages have been discarded:
|
%% Warn senders that their messages have been discarded:
|
||||||
discard_warn_sender(Msgs) ->
|
discard_warn_sender(Msgs) ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun(#offline_msg{from=From, to=To, packet=Packet0}) ->
|
fun(#offline_msg{from=From, to=To, packet=Packet}) ->
|
||||||
Packet = case Packet0 of
|
|
||||||
#xmlelement{} = P ->
|
|
||||||
exmpp_xml:xmlelement_to_xmlel(P,
|
|
||||||
[?DEFAULT_NS], ?PREFIXED_NS);
|
|
||||||
#xmlel{} = P ->
|
|
||||||
P
|
|
||||||
end,
|
|
||||||
ErrText = "Your contact offline message queue is full. The message has been discarded.",
|
ErrText = "Your contact offline message queue is full. The message has been discarded.",
|
||||||
Error = exmpp_stanza:error('resource-constraint',
|
Error = exmpp_stanza:error('resource-constraint',
|
||||||
{"en", ErrText}),
|
{"en", ErrText}),
|
||||||
Err = exmpp_stanza:reply_with_error(Packet, Error),
|
Err = exmpp_stanza:reply_with_error(Packet, Error),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
jlib:from_old_jid(To),
|
To,
|
||||||
jlib:from_old_jid(From), Err)
|
From, Err)
|
||||||
end, Msgs).
|
end, Msgs).
|
||||||
|
|
||||||
|
|
||||||
@ -482,10 +532,21 @@ webadmin_page(_, Host,
|
|||||||
webadmin_page(Acc, _, _) -> Acc.
|
webadmin_page(Acc, _, _) -> Acc.
|
||||||
|
|
||||||
user_queue(User, Server, Query, Lang) ->
|
user_queue(User, Server, Query, Lang) ->
|
||||||
US = {exmpp_stringprep:nodeprep(User), exmpp_stringprep:nameprep(Server)},
|
{US, Msgs, Res} = try
|
||||||
Res = user_queue_parse_query(US, Query),
|
US0 = {
|
||||||
Msgs = lists:keysort(#offline_msg.timestamp,
|
exmpp_stringprep:nodeprep(User),
|
||||||
mnesia:dirty_read({offline_msg, US})),
|
exmpp_stringprep:nameprep(Server)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
US0,
|
||||||
|
lists:keysort(#offline_msg.timestamp,
|
||||||
|
mnesia:dirty_read({offline_msg, US0})),
|
||||||
|
user_queue_parse_query(US0, Query)
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
_ ->
|
||||||
|
{{"invalid", "invalid"}, [], nothing}
|
||||||
|
end,
|
||||||
FMsgs =
|
FMsgs =
|
||||||
lists:map(
|
lists:map(
|
||||||
fun(#offline_msg{timestamp = TimeStamp, from = From, to = To,
|
fun(#offline_msg{timestamp = TimeStamp, from = From, to = To,
|
||||||
@ -497,11 +558,9 @@ user_queue(User, Server, Query, Lang) ->
|
|||||||
io_lib:format(
|
io_lib:format(
|
||||||
"~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w",
|
"~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w",
|
||||||
[Year, Month, Day, Hour, Minute, Second])),
|
[Year, Month, Day, Hour, Minute, Second])),
|
||||||
SFrom = exmpp_jid:jid_to_list(jlib:from_old_jid(From)),
|
SFrom = exmpp_jid:jid_to_list(From),
|
||||||
STo = exmpp_jid:jid_to_list(jlib:from_old_jid(To)),
|
STo = exmpp_jid:jid_to_list(To),
|
||||||
Packet0 = exmpp_xml:xmlelement_to_xmlel(Packet,
|
Packet1 = exmpp_stanza:set_jids(Packet, SFrom, STo),
|
||||||
[?DEFAULT_NS], ?PREFIXED_NS),
|
|
||||||
Packet1 = exmpp_stanza:set_jids(Packet0, SFrom, STo),
|
|
||||||
FPacket = exmpp_xml:node_to_list(
|
FPacket = exmpp_xml:node_to_list(
|
||||||
exmpp_xml:indent_document(Packet1, <<" ">>),
|
exmpp_xml:indent_document(Packet1, <<" ">>),
|
||||||
[?DEFAULT_NS], ?PREFIXED_NS),
|
[?DEFAULT_NS], ?PREFIXED_NS),
|
||||||
@ -571,8 +630,16 @@ us_to_list({User, Server}) ->
|
|||||||
exmpp_jid:jid_to_list(User, Server).
|
exmpp_jid:jid_to_list(User, Server).
|
||||||
|
|
||||||
webadmin_user(Acc, User, Server, Lang) ->
|
webadmin_user(Acc, User, Server, Lang) ->
|
||||||
US = {exmpp_stringprep:nodeprep(User), exmpp_stringprep:nameprep(Server)},
|
FQueueLen = try
|
||||||
QueueLen = length(mnesia:dirty_read({offline_msg, US})),
|
US = {
|
||||||
FQueueLen = [?AC("queue/",
|
exmpp_stringprep:nodeprep(User),
|
||||||
integer_to_list(QueueLen))],
|
exmpp_stringprep:nameprep(Server)
|
||||||
|
},
|
||||||
|
QueueLen = length(mnesia:dirty_read({offline_msg, US})),
|
||||||
|
[?AC("queue/",
|
||||||
|
integer_to_list(QueueLen))]
|
||||||
|
catch
|
||||||
|
_ ->
|
||||||
|
[?C("?")]
|
||||||
|
end,
|
||||||
Acc ++ [?XCT("h3", "Offline Messages:")] ++ FQueueLen.
|
Acc ++ [?XCT("h3", "Offline Messages:")] ++ FQueueLen.
|
||||||
|
Loading…
Reference in New Issue
Block a user