Fix support for static_modules in mod_adhoc, announce, disco, last, offline

This commit is contained in:
Badlop 2011-07-11 19:46:26 +02:00
parent 0d7e69a65e
commit 0b1f3ca148
10 changed files with 87 additions and 52 deletions

View File

@ -611,6 +611,12 @@
%%
{static_modules,
[
%% {mod_adhoc, []},
%% {mod_announce, []},
%% {mod_disco, []},
%% {mod_echo, [{prefix, "echo"}]},
%% {mod_last, []},
%% {mod_offline, []}
]}.

View File

@ -40,6 +40,7 @@
loaded_modules_with_opts/1,
get_hosts/2,
get_module_proc/2,
get_module_proc_existing/2,
expand_host_name/3,
is_loaded/2]).
@ -194,7 +195,13 @@ get_module_opt(Host, Module, Opt, Default) ->
OptsList = ets:lookup(ejabberd_modules, {Module, Host}),
case OptsList of
[] ->
Default;
OptsList2 = ets:lookup(ejabberd_modules, {Module, global}),
case OptsList2 of
[] ->
Default;
[#ejabberd_module{opts = Opts} | _] ->
get_opt(Opt, Opts, Default)
end;
[#ejabberd_module{opts = Opts} | _] ->
get_opt(Opt, Opts, Default)
end.
@ -260,6 +267,15 @@ get_hosts(Opts, Prefix) ->
Hosts
end.
get_module_proc_existing(Host, Base) ->
Proc = get_module_proc(Host, Base),
%% If the process doesn't exist for Host, it may exist for global
case {whereis(Proc), Host == global} of
{undefined, false} -> get_module_proc(global, Base);
{undefined, true} -> not_existing;
{_, _} -> Proc
end.
get_module_proc(Host, Base) when is_binary(Host) ->
get_module_proc(binary_to_list(Host), Base);
get_module_proc(global, Base) ->
@ -269,8 +285,11 @@ get_module_proc(Host, {frontend, Base}) ->
get_module_proc(Host, Base) ->
list_to_atom(atom_to_list(Base) ++ "_" ++ Host).
%% @spec(Host::string() | global, Module::atom()) -> true | false
%% @doc Check if the module is loaded in this host (or global), or not.
is_loaded(Host, Module) ->
ets:member(ejabberd_modules, {Module, Host}).
ets:member(ejabberd_modules, {Module, Host})
orelse ets:member(ejabberd_modules, {Module, global}).
expand_host_name(Host, Opts, DefaultPrefix) ->
case Host of

View File

@ -118,6 +118,9 @@ table_info(Host, Tab, InfoKey) ->
-spec create_table(atom(), storage_host(), storage_table(), list()) ->
tuple().
create_table(Backend, global, Tab, Def) ->
[create_table(Backend, list_to_binary(Host), Tab, Def) || Host <- ejabberd_hosts:get_hosts(ejabberd)];
create_table(mnesia, Host, Tab, Def) ->
MDef = filter_mnesia_tabdef(Def),
define_table(mnesia, Host, Tab, #mnesia_def{table = Tab,

View File

@ -32,8 +32,9 @@ migrate_mnesia(Host, Table, Migrations) ->
end
end, DifferentTableName).
migrate_mnesia1(Host, Table, {OldTable, OldAttributes, MigrateFun}) ->
HostB = list_to_binary(Host),
migrate_mnesia1(Host, Table, {OldTable, OldAttributes, MigrateFun}) when is_list(Host) ->
migrate_mnesia1(list_to_binary(Host), Table, {OldTable, OldAttributes, MigrateFun});
migrate_mnesia1(HostB, Table, {OldTable, OldAttributes, MigrateFun}) ->
case (catch mnesia:table_info(OldTable, attributes)) of
OldAttributes ->
if

View File

@ -47,8 +47,9 @@
-include("ejabberd.hrl").
-include("adhoc.hrl").
start(Host, Opts) ->
HostB = list_to_binary(Host),
start(Host, Opts) when is_list(Host) ->
start(list_to_binary(Host), Opts);
start(HostB, Opts) ->
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
gen_iq_handler:add_iq_handler(ejabberd_local, HostB, ?NS_ADHOC,

View File

@ -57,8 +57,9 @@
-define(NS_ADMINL(Sub), ["http:","jabber.org","protocol","admin", Sub]).
tokenize(Node) -> string:tokens(Node, "/#").
start(Host, _Opts) ->
HostB = list_to_binary(Host),
start(Host, Opts) when is_list(Host) ->
start(list_to_binary(Host), Opts);
start(HostB, _Opts) ->
mnesia:create_table(motd, [{disc_copies, [node()]},
{attributes, record_info(fields, motd)}]),
mnesia:create_table(motd_users, [{disc_copies, [node()]},
@ -73,7 +74,7 @@ start(Host, _Opts) ->
ejabberd_hooks:add(adhoc_local_commands, HostB, ?MODULE, announce_commands, 50),
ejabberd_hooks:add(user_available_hook, HostB,
?MODULE, send_motd, 50),
register(gen_mod:get_module_proc(Host, ?PROCNAME),
register(gen_mod:get_module_proc(HostB, ?PROCNAME),
proc_lib:spawn(?MODULE, init, [])).
init() ->
@ -135,7 +136,7 @@ announce(From, To, Packet) ->
case {exmpp_jid:prep_node(To), exmpp_jid:prep_resource(To)} of
{undefined, Res} ->
Name = Packet#xmlel.name,
Proc = gen_mod:get_module_proc(exmpp_jid:prep_domain_as_list(To), ?PROCNAME),
Proc = gen_mod:get_module_proc_existing(exmpp_jid:prep_domain_as_list(To), ?PROCNAME),
case {Res, Name} of
{<<"announce/all">>, 'message'} ->
Proc ! {announce_all, From, To, Packet},
@ -541,7 +542,7 @@ handle_adhoc_form(From, To,
node = Node,
sessionid = SessionID},
Fields) ->
LServer = exmpp_jid:prep_domain_as_list(To),
LServerB = exmpp_jid:prep_domain(To),
Confirm = case lists:keysearch("confirm", 1, Fields) of
{value, {"confirm", ["true"]}} ->
true;
@ -582,7 +583,7 @@ handle_adhoc_form(From, To,
[]
end},
Proc = gen_mod:get_module_proc(LServer, ?PROCNAME),
Proc = gen_mod:get_module_proc_existing(LServerB, ?PROCNAME),
case {Node, Body} of
{?NS_ADMIN_s ++ "#delete-motd", _} ->
if Confirm ->

View File

@ -53,8 +53,9 @@
-include("ejabberd.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
start(Host, Opts) ->
HostB = list_to_binary(Host),
start(Host, Opts) when is_list(Host) ->
start(list_to_binary(Host), Opts);
start(HostB, Opts) ->
ejabberd_local:refresh_iq_handlers(),
@ -75,7 +76,7 @@ start(Host, Opts) ->
catch ets:new(disco_extra_domains, [named_table, ordered_set, public]),
ExtraDomains = gen_mod:get_opt(extra_domains, Opts, []),
lists:foreach(fun(Domain) -> register_extra_domain(list_to_binary(Host), Domain) end,
lists:foreach(fun(Domain) -> register_extra_domain(HostB, Domain) end,
ExtraDomains),
catch ets:new(disco_sm_features, [named_table, ordered_set, public]),
catch ets:new(disco_sm_nodes, [named_table, ordered_set, public]),
@ -106,7 +107,7 @@ stop(Host) ->
ok.
register_feature(HostB, Feature) when is_binary(HostB) ->
register_feature(HostB, Feature) ->
catch ets:new(disco_features, [named_table, ordered_set, public]),
ets:insert(disco_features, {{Feature, HostB}}).
@ -114,11 +115,11 @@ unregister_feature(HostB, Feature) ->
catch ets:new(disco_features, [named_table, ordered_set, public]),
ets:delete(disco_features, {Feature, HostB}).
register_extra_domain(HostB, Domain) when is_binary(HostB) ->
register_extra_domain(HostB, Domain) ->
catch ets:new(disco_extra_domains, [named_table, ordered_set, public]),
ets:insert(disco_extra_domains, {{Domain, HostB}}).
unregister_extra_domain(HostB, Domain) when is_binary(HostB) ->
unregister_extra_domain(HostB, Domain) ->
catch ets:new(disco_extra_domains, [named_table, ordered_set, public]),
ets:delete(disco_extra_domains, {Domain, HostB}).
@ -242,14 +243,14 @@ get_local_services(Acc, _From, To, <<>>, _Lang) ->
empty -> []
end,
Host = exmpp_jid:prep_domain_as_list(To),
NHost = ejabberd:normalize_host(Host),
NHostB = list_to_binary(ejabberd:normalize_host(Host)),
{result,
lists:usort(
lists:map(fun domain_to_xml/1,
get_vh_services(Host) ++
ets:select(disco_extra_domains,
ets:fun2ms(fun ({{Service, H}})
when H =:= NHost;
when H =:= NHostB;
H =:= global ->
Service
end)))

View File

@ -77,17 +77,18 @@
-record(last_activity, {user_host, timestamp, status}).
start(Host, Opts) ->
HostB = list_to_binary(Host),
start(Host, Opts) when is_list(Host) ->
start(list_to_binary(Host), Opts);
start(HostB, Opts) ->
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
Backend = gen_mod:get_opt(backend, Opts, mnesia),
gen_storage:create_table(Backend, HostB, last_activity,
[{disc_copies, [node()]},
{odbc_host, Host},
{odbc_host, HostB},
{attributes, record_info(fields, last_activity)},
{types, [{user_host, {text, text}},
{timestamp, bigint}]}]),
update_table(Host, Backend),
update_table(HostB, Backend),
gen_iq_handler:add_iq_handler(ejabberd_local, HostB, ?NS_LAST_ACTIVITY,
?MODULE, process_local_iq, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_sm, HostB, ?NS_LAST_ACTIVITY,
@ -97,8 +98,9 @@ start(Host, Opts) ->
ejabberd_hooks:add(unset_presence_hook, HostB,
?MODULE, on_presence_update, 50).
stop(Host) ->
HostB = list_to_binary(Host),
stop(Host) when is_list(Host) ->
stop(list_to_binary(Host));
stop(HostB) ->
ejabberd_hooks:delete(remove_user, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:delete(unset_presence_hook, HostB,
@ -252,9 +254,12 @@ remove_user(User, Server) when is_binary(User), is_binary(Server) ->
ok
end.
update_table(Host, mnesia) ->
update_table(global, Storage) ->
[update_table(HostB, Storage) || HostB <- ejabberd_hosts:get_hosts(ejabberd)];
update_table(HostB, mnesia) ->
gen_storage_migration:migrate_mnesia(
Host, last_activity,
HostB, last_activity,
[{last_activity, [us, timestamp, status],
fun({last_activity, {U, S}, Timestamp, Status}) ->
U1 = case U of
@ -266,14 +271,14 @@ update_table(Host, mnesia) ->
timestamp = Timestamp,
status = list_to_binary(Status)}
end}]);
update_table(Host, odbc) ->
update_table(HostB, odbc) ->
gen_storage_migration:migrate_odbc(
Host, [last_activity],
HostB, [last_activity],
[{"last", ["username", "seconds", "state"],
fun(_, Username, STimeStamp, Status) ->
case catch list_to_integer(STimeStamp) of
TimeStamp when is_integer(TimeStamp) ->
[#last_activity{user_host = {Username, Host},
[#last_activity{user_host = {Username, HostB},
timestamp = TimeStamp,
status = Status}];
_ ->

View File

@ -112,12 +112,14 @@
%% default value for the maximum number of user messages
-define(MAX_USER_MESSAGES, infinity).
start(Host, Opts) ->
HostB = list_to_binary(Host),
start(Host, Opts) when is_list(Host) ->
start(list_to_binary(Host), Opts);
start(HostB, Opts) ->
% Host = binary_to_list(HostB),
Backend = gen_mod:get_opt(backend, Opts, mnesia),
gen_storage:create_table(Backend, HostB, offline_msg,
[{disc_only_copies, [node()]},
{odbc_host, Host},
{odbc_host, HostB},
{type, bag},
{attributes, record_info(fields, offline_msg)},
{types, [{user_host, {text, text}},
@ -125,7 +127,7 @@ start(Host, Opts) ->
{expire, bigint},
{from, jid},
{to, jid}]}]),
update_table(Host, Backend),
update_table(HostB, Backend),
ejabberd_hooks:add(offline_message_hook, HostB,
?MODULE, store_packet, 50),
ejabberd_hooks:add(resend_offline_messages_hook, HostB,
@ -145,7 +147,7 @@ start(Host, Opts) ->
ejabberd_hooks:add(webadmin_user_parse_query, HostB,
?MODULE, webadmin_user_parse_query, 50),
AccessMaxOfflineMsgs = gen_mod:get_opt(access_max_user_messages, Opts, max_user_offline_messages),
register(gen_mod:get_module_proc(Host, ?PROCNAME),
register(gen_mod:get_module_proc(HostB, ?PROCNAME),
spawn(?MODULE, loop, [AccessMaxOfflineMsgs])).
stanza_to_store(Stanza) ->
@ -258,7 +260,7 @@ store_packet(From, To, Packet) ->
LServer = exmpp_jid:prep_domain(To),
TimeStamp = make_timestamp(),
Expire = find_x_expire(TimeStamp, Packet#xmlel.children),
gen_mod:get_module_proc(LServer, ?PROCNAME) !
gen_mod:get_module_proc_existing(LServer, ?PROCNAME) !
#offline_msg{user_host = {LUser, LServer},
timestamp = TimeStamp,
expire = Expire,
@ -464,6 +466,9 @@ remove_user(User, Server) when is_binary(User), is_binary(Server) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
update_table(global, Storage) ->
[update_table(HostB, Storage) || HostB <- ejabberd_hosts:get_hosts(ejabberd)];
update_table(Host, mnesia) ->
gen_storage_migration:migrate_mnesia(
Host, offline_msg,
@ -720,8 +725,8 @@ get_messages_subset2(Max, Length, MsgsAll) ->
MsgsFirstN ++ [IntermediateMsg] ++ MsgsLastN.
webadmin_user(Acc, User, Server, Lang) ->
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
LUser = list_to_binary(exmpp_stringprep:nodeprep(User)),
LServer = list_to_binary(exmpp_stringprep:nameprep(Server)),
QueueLen = get_queue_length(LUser, LServer),
FQueueLen = [?AC("queue/", integer_to_list(QueueLen))],
Acc ++ [?XCT("h3", "Offline Messages:")] ++ FQueueLen ++ [?C(" "), ?INPUTT("submit", "removealloffline", "Remove All Offline Messages")].

View File

@ -1658,8 +1658,7 @@ list_users_in_diapason(Host, Diap, Lang, URLFunc) ->
Sub = lists:sublist(SUsers, N1, N2 - N1 + 1),
[list_given_users(Host, Sub, "../../", Lang, URLFunc)].
list_given_users(Host, Users, Prefix, Lang, URLFunc) ->
ModOffline = get_offlinemsg_module(Host),
list_given_users(_Host, Users, Prefix, Lang, URLFunc) ->
?XE('table',
[?XE('thead',
[?XE('tr',
@ -1672,7 +1671,7 @@ list_given_users(Host, Users, Prefix, Lang, URLFunc) ->
ServerB = list_to_binary(Server),
UserB = list_to_binary(User),
US = {UserB, ServerB},
QueueLenStr = get_offlinemsg_length(ModOffline, User, Server),
QueueLenStr = get_offlinemsg_length(User, Server),
FQueueLen = [?AC(URLFunc({users_queue, Prefix,
User, Server}),
QueueLenStr)],
@ -1707,16 +1706,10 @@ list_given_users(Host, Users, Prefix, Lang, URLFunc) ->
end, Users)
)]).
get_offlinemsg_length(ModOffline, User, Server) ->
case ModOffline of
none -> "disabled";
_ -> pretty_string_int(ModOffline:get_queue_length(list_to_binary(User), list_to_binary(Server)))
end.
get_offlinemsg_module(Server) ->
case [mod_offline] -- gen_mod:loaded_modules(Server) of
[mod_offline] -> none;
[] -> mod_offline
get_offlinemsg_length(User, Server) ->
case gen_mod:is_loaded(Server, mod_offline) of
false -> "disabled";
true -> pretty_string_int(mod_offline:get_queue_length(list_to_binary(User), list_to_binary(Server)))
end.
us_to_list({User, Server}) ->