aboutsummaryrefslogtreecommitdiff
path: root/src/mod_announce.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mod_announce.erl')
-rw-r--r--src/mod_announce.erl180
1 files changed, 150 insertions, 30 deletions
diff --git a/src/mod_announce.erl b/src/mod_announce.erl
index b8164aab0..495eac260 100644
--- a/src/mod_announce.erl
+++ b/src/mod_announce.erl
@@ -20,8 +20,8 @@
-include("ejabberd.hrl").
-include("jlib.hrl").
--record(motd, {id, packet}).
--record(motd_users, {luser, dummy = []}).
+-record(motd, {server, packet}).
+-record(motd_users, {us, dummy = []}).
-define(PROCNAME, ejabberd_announce).
@@ -30,6 +30,7 @@ start(_) ->
{attributes, record_info(fields, motd)}]),
mnesia:create_table(motd_users, [{disc_copies, [node()]},
{attributes, record_info(fields, motd_users)}]),
+ update_tables(),
ejabberd_hooks:add(local_send_to_resource_hook,
?MODULE, announce, 50),
ejabberd_hooks:add(user_available_hook,
@@ -47,6 +48,9 @@ loop() ->
{announce_online, From, To, Packet} ->
announce_online(From, To, Packet),
loop();
+ {announce_all_hosts_online, From, To, Packet} ->
+ announce_all_hosts_online(From, To, Packet),
+ loop();
{announce_motd, From, To, Packet} ->
announce_motd(From, To, Packet),
loop();
@@ -79,6 +83,9 @@ announce(From, To, Packet) ->
{"announce/online", "message"} ->
?PROCNAME ! {announce_online, From, To, Packet},
stop;
+ {"announce/all-hosts/online", "message"} ->
+ ?PROCNAME ! {announce_all_hosts_online, From, To, Packet},
+ stop;
{"announce/motd", "message"} ->
?PROCNAME ! {announce_motd, From, To, Packet},
stop;
@@ -102,13 +109,12 @@ announce_all(From, To, Packet) ->
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
ejabberd_router:route(To, From, Err);
allow ->
- Server = ?MYNAME,
- Local = jlib:make_jid("", Server, ""),
+ Local = jlib:make_jid("", To#jid.server, ""),
lists:foreach(
- fun(U) ->
- Dest = jlib:make_jid(U, Server, ""),
+ fun({User, Server}) ->
+ Dest = jlib:make_jid(User, Server, ""),
ejabberd_router:route(Local, Dest, Packet)
- end, ejabberd_auth:dirty_get_registered_users())
+ end, ejabberd_auth:get_vh_registered_users(To#jid.lserver))
end.
announce_online(From, To, Packet) ->
@@ -118,15 +124,28 @@ announce_online(From, To, Packet) ->
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
ejabberd_router:route(To, From, Err);
allow ->
- announce_online1(ejabberd_sm:dirty_get_sessions_list(), Packet)
+ announce_online1(ejabberd_sm:get_vh_session_list(To#jid.lserver),
+ To#jid.server,
+ Packet)
end.
-announce_online1(Sessions, Packet) ->
- Server = ?MYNAME,
+announce_all_hosts_online(From, To, Packet) ->
+ Access = gen_mod:get_module_opt(?MODULE, access, none),
+ case acl:match_rule(Access, From) of
+ deny ->
+ Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
+ ejabberd_router:route(To, From, Err);
+ allow ->
+ announce_online1(ejabberd_sm:dirty_get_sessions_list(),
+ To#jid.server,
+ Packet)
+ end.
+
+announce_online1(Sessions, Server, Packet) ->
Local = jlib:make_jid("", Server, ""),
lists:foreach(
- fun({U, R}) ->
- Dest = jlib:make_jid(U, Server, R),
+ fun({U, S, R}) ->
+ Dest = jlib:make_jid(U, S, R),
ejabberd_router:route(Local, Dest, Packet)
end, Sessions).
@@ -137,13 +156,13 @@ announce_motd(From, To, Packet) ->
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
ejabberd_router:route(To, From, Err);
allow ->
- announce_motd_update(Packet),
- Sessions = ejabberd_sm:dirty_get_sessions_list(),
- announce_online1(Sessions, Packet),
+ announce_motd_update(To#jid.lserver, Packet),
+ Sessions = ejabberd_sm:get_vh_session_list(To#jid.lserver),
+ announce_online1(Sessions, To#jid.server, Packet),
F = fun() ->
lists:foreach(
- fun({U, _R}) ->
- mnesia:write(#motd_users{luser = U})
+ fun({U, S, _R}) ->
+ mnesia:write(#motd_users{us = {U, S}})
end, Sessions)
end,
mnesia:transaction(F)
@@ -156,13 +175,13 @@ announce_motd_update(From, To, Packet) ->
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
ejabberd_router:route(To, From, Err);
allow ->
- announce_motd_update(Packet)
+ announce_motd_update(To#jid.lserver, Packet)
end.
-announce_motd_update(Packet) ->
- announce_motd_delete(),
+announce_motd_update(LServer, Packet) ->
+ announce_motd_delete(LServer),
F = fun() ->
- mnesia:write(#motd{id = motd, packet = Packet})
+ mnesia:write(#motd{server = LServer, packet = Packet})
end,
mnesia:transaction(F).
@@ -173,24 +192,36 @@ announce_motd_delete(From, To, Packet) ->
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
ejabberd_router:route(To, From, Err);
allow ->
- announce_motd_delete()
+ announce_motd_delete(To#jid.lserver)
end.
-announce_motd_delete() ->
- mnesia:clear_table(motd),
- mnesia:clear_table(motd_users).
+announce_motd_delete(LServer) ->
+ F = fun() ->
+ mnesia:delete({motd, LServer}),
+ mnesia:write_lock_table(motd_users),
+ Users = mnesia:select(
+ motd_users,
+ [{#motd_users{us = '$1', _ = '_'},
+ [{'==', {element, 2, '$1'}, LServer}],
+ ['$1']}]),
+ lists:foreach(fun(US) ->
+ mnesia:delete({motd_users, US})
+ end, Users)
+ end,
+ mnesia:transaction(F).
-send_motd(#jid{luser = LUser} = JID) ->
- case catch mnesia:dirty_read({motd, motd}) of
+send_motd(#jid{luser = LUser, lserver = LServer} = JID) ->
+ case catch mnesia:dirty_read({motd, LServer}) of
[#motd{packet = Packet}] ->
- case catch mnesia:dirty_read({motd_users, LUser}) of
+ US = {LUser, LServer},
+ case catch mnesia:dirty_read({motd_users, US}) of
[#motd_users{}] ->
ok;
_ ->
- Local = jlib:make_jid("", ?MYNAME, ""),
+ Local = jlib:make_jid("", LServer, ""),
ejabberd_router:route(Local, JID, Packet),
F = fun() ->
- mnesia:write(#motd_users{luser = LUser})
+ mnesia:write(#motd_users{us = US})
end,
mnesia:transaction(F)
end;
@@ -198,3 +229,92 @@ send_motd(#jid{luser = LUser} = JID) ->
ok
end.
+
+update_tables() ->
+ update_motd_table(),
+ update_motd_users_table().
+
+update_motd_table() ->
+ Fields = record_info(fields, motd),
+ case mnesia:table_info(motd, attributes) of
+ Fields ->
+ ok;
+ [id, packet] ->
+ ?INFO_MSG("Converting motd table from "
+ "{id, packet} format", []),
+ Host = ?MYNAME,
+ {atomic, ok} = mnesia:create_table(
+ mod_announce_tmp_table,
+ [{disc_only_copies, [node()]},
+ {type, bag},
+ {local_content, true},
+ {record_name, motd},
+ {attributes, record_info(fields, motd)}]),
+ mnesia:transform_table(motd, ignore, Fields),
+ F1 = fun() ->
+ mnesia:write_lock_table(mod_announce_tmp_table),
+ mnesia:foldl(
+ fun(#motd{server = _} = R, _) ->
+ mnesia:dirty_write(
+ mod_announce_tmp_table,
+ R#motd{server = Host})
+ end, ok, motd)
+ end,
+ mnesia:transaction(F1),
+ mnesia:clear_table(motd),
+ F2 = fun() ->
+ mnesia:write_lock_table(motd),
+ mnesia:foldl(
+ fun(R, _) ->
+ mnesia:dirty_write(R)
+ end, ok, mod_announce_tmp_table)
+ end,
+ mnesia:transaction(F2),
+ mnesia:delete_table(mod_announce_tmp_table);
+ _ ->
+ ?INFO_MSG("Recreating motd table", []),
+ mnesia:transform_table(motd, ignore, Fields)
+ end.
+
+
+update_motd_users_table() ->
+ Fields = record_info(fields, motd_users),
+ case mnesia:table_info(motd_users, attributes) of
+ Fields ->
+ ok;
+ [luser, dummy] ->
+ ?INFO_MSG("Converting motd_users table from "
+ "{luser, dummy} format", []),
+ Host = ?MYNAME,
+ {atomic, ok} = mnesia:create_table(
+ mod_announce_tmp_table,
+ [{disc_only_copies, [node()]},
+ {type, bag},
+ {local_content, true},
+ {record_name, motd_users},
+ {attributes, record_info(fields, motd_users)}]),
+ mnesia:transform_table(motd_users, ignore, Fields),
+ F1 = fun() ->
+ mnesia:write_lock_table(mod_announce_tmp_table),
+ mnesia:foldl(
+ fun(#motd_users{us = U} = R, _) ->
+ mnesia:dirty_write(
+ mod_announce_tmp_table,
+ R#motd_users{us = {U, Host}})
+ end, ok, motd_users)
+ end,
+ mnesia:transaction(F1),
+ mnesia:clear_table(motd_users),
+ F2 = fun() ->
+ mnesia:write_lock_table(motd_users),
+ mnesia:foldl(
+ fun(R, _) ->
+ mnesia:dirty_write(R)
+ end, ok, mod_announce_tmp_table)
+ end,
+ mnesia:transaction(F2),
+ mnesia:delete_table(mod_announce_tmp_table);
+ _ ->
+ ?INFO_MSG("Recreating motd_users table", []),
+ mnesia:transform_table(motd_users, ignore, Fields)
+ end.