mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
* (all): Enhanced virtual hosting support
SVN Revision: 370
This commit is contained in:
parent
cb90075327
commit
4098c3ecba
@ -1,3 +1,7 @@
|
|||||||
|
2005-06-20 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
|
* (all): Enhanced virtual hosting support
|
||||||
|
|
||||||
2005-05-28 Alexey Shchepin <alexey@sevcom.net>
|
2005-05-28 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
* src/web/ejabberd_web_admin.erl: Bugfix
|
* src/web/ejabberd_web_admin.erl: Bugfix
|
||||||
|
93
src/acl.erl
93
src/acl.erl
@ -11,12 +11,12 @@
|
|||||||
-vsn('$Revision$ ').
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
-export([start/0,
|
-export([start/0,
|
||||||
to_record/2,
|
to_record/3,
|
||||||
add/2,
|
add/3,
|
||||||
add_list/2,
|
add_list/3,
|
||||||
match_rule/2,
|
match_rule/3,
|
||||||
% for debugging only
|
% for debugging only
|
||||||
match_acl/2]).
|
match_acl/3]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
|
|
||||||
@ -30,30 +30,35 @@ start() ->
|
|||||||
mnesia:add_table_copy(acl, node(), ram_copies),
|
mnesia:add_table_copy(acl, node(), ram_copies),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
to_record(ACLName, ACLSpec) ->
|
to_record(Host, ACLName, ACLSpec) ->
|
||||||
#acl{aclname = ACLName, aclspec = ACLSpec}.
|
#acl{aclname = {ACLName, Host}, aclspec = ACLSpec}.
|
||||||
|
|
||||||
add(ACLName, ACLSpec) ->
|
add(Host, ACLName, ACLSpec) ->
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
mnesia:write(#acl{aclname = ACLName, aclspec = ACLSpec})
|
mnesia:write(#acl{aclname = {ACLName, Host},
|
||||||
|
aclspec = ACLSpec})
|
||||||
end,
|
end,
|
||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
add_list(ACLs, Clear) ->
|
add_list(Host, ACLs, Clear) ->
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
if
|
if
|
||||||
Clear ->
|
Clear ->
|
||||||
Ks = mnesia:all_keys(acl),
|
Ks = mnesia:select(
|
||||||
|
acl, [{{acl, {'$1', Host}, '$2'}, [], ['$1']}]),
|
||||||
lists:foreach(fun(K) ->
|
lists:foreach(fun(K) ->
|
||||||
mnesia:delete({acl, K})
|
mnesia:delete({acl, {K, Host}})
|
||||||
end, Ks);
|
end, Ks);
|
||||||
true ->
|
true ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
lists:foreach(fun(ACL) ->
|
lists:foreach(fun(ACL) ->
|
||||||
case ACL of
|
case ACL of
|
||||||
#acl{} ->
|
#acl{aclname = ACLName,
|
||||||
mnesia:write(ACL)
|
aclspec = ACLSpec} ->
|
||||||
|
mnesia:write(
|
||||||
|
#acl{aclname = {ACLName, Host},
|
||||||
|
aclspec = ACLSpec})
|
||||||
end
|
end
|
||||||
end, ACLs)
|
end, ACLs)
|
||||||
end,
|
end,
|
||||||
@ -66,30 +71,53 @@ add_list(ACLs, Clear) ->
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
match_rule(Rule, JID) ->
|
match_rule(global, Rule, JID) ->
|
||||||
case Rule of
|
case Rule of
|
||||||
all -> allow;
|
all -> allow;
|
||||||
none -> deny;
|
none -> deny;
|
||||||
_ ->
|
_ ->
|
||||||
case ejabberd_config:get_global_option({access, Rule}) of
|
case ejabberd_config:get_global_option({access, Rule, global}) of
|
||||||
|
undefined ->
|
||||||
|
deny;
|
||||||
|
GACLs ->
|
||||||
|
match_acls(GACLs, JID, global)
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
match_rule(Host, Rule, JID) ->
|
||||||
|
case Rule of
|
||||||
|
all -> allow;
|
||||||
|
none -> deny;
|
||||||
|
_ ->
|
||||||
|
case ejabberd_config:get_global_option({access, Rule, global}) of
|
||||||
|
undefined ->
|
||||||
|
case ejabberd_config:get_global_option({access, Rule, Host}) of
|
||||||
undefined ->
|
undefined ->
|
||||||
deny;
|
deny;
|
||||||
ACLs ->
|
ACLs ->
|
||||||
match_acls(ACLs, JID)
|
match_acls(ACLs, JID, Host)
|
||||||
|
end;
|
||||||
|
GACLs ->
|
||||||
|
case ejabberd_config:get_global_option({access, Rule, Host}) of
|
||||||
|
undefined ->
|
||||||
|
match_acls(GACLs, JID, Host);
|
||||||
|
ACLs ->
|
||||||
|
match_acls(GACLs ++ ACLs, JID, Host)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
match_acls([], _) ->
|
match_acls([], _, Host) ->
|
||||||
deny;
|
deny;
|
||||||
match_acls([{Access, ACL} | ACLs], JID) ->
|
match_acls([{Access, ACL} | ACLs], JID, Host) ->
|
||||||
case match_acl(ACL, JID) of
|
case match_acl(ACL, JID, Host) of
|
||||||
true ->
|
true ->
|
||||||
Access;
|
Access;
|
||||||
_ ->
|
_ ->
|
||||||
match_acls(ACLs, JID)
|
match_acls(ACLs, JID, Host)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
match_acl(ACL, JID) ->
|
match_acl(ACL, JID, Host) ->
|
||||||
case ACL of
|
case ACL of
|
||||||
all -> true;
|
all -> true;
|
||||||
none -> false;
|
none -> false;
|
||||||
@ -100,14 +128,20 @@ match_acl(ACL, JID) ->
|
|||||||
all ->
|
all ->
|
||||||
true;
|
true;
|
||||||
{user, U} ->
|
{user, U} ->
|
||||||
(U == User) andalso (?MYNAME == Server);
|
(U == User)
|
||||||
|
andalso
|
||||||
|
((Host == Server) orelse
|
||||||
|
((Host == global) andalso
|
||||||
|
lists:member(Server, ?MYHOSTS)));
|
||||||
{user, U, S} ->
|
{user, U, S} ->
|
||||||
(U == User) andalso (S == Server);
|
(U == User) andalso (S == Server);
|
||||||
{server, S} ->
|
{server, S} ->
|
||||||
S == Server;
|
S == Server;
|
||||||
{user_regexp, UR} ->
|
{user_regexp, UR} ->
|
||||||
(?MYNAME == Server) andalso
|
((Host == Server) orelse
|
||||||
is_regexp_match(User, UR);
|
((Host == global) andalso
|
||||||
|
lists:member(Server, ?MYHOSTS)))
|
||||||
|
andalso is_regexp_match(User, UR);
|
||||||
{user_regexp, UR, S} ->
|
{user_regexp, UR, S} ->
|
||||||
(S == Server) andalso
|
(S == Server) andalso
|
||||||
is_regexp_match(User, UR);
|
is_regexp_match(User, UR);
|
||||||
@ -117,7 +151,10 @@ match_acl(ACL, JID) ->
|
|||||||
is_regexp_match(Server, SR) andalso
|
is_regexp_match(Server, SR) andalso
|
||||||
is_regexp_match(User, UR);
|
is_regexp_match(User, UR);
|
||||||
{user_glob, UR} ->
|
{user_glob, UR} ->
|
||||||
(?MYNAME == Server) andalso
|
((Host == Server) orelse
|
||||||
|
((Host == global) andalso
|
||||||
|
lists:member(Server, ?MYHOSTS)))
|
||||||
|
andalso
|
||||||
is_glob_match(User, UR);
|
is_glob_match(User, UR);
|
||||||
{user_glob, UR, S} ->
|
{user_glob, UR, S} ->
|
||||||
(S == Server) andalso
|
(S == Server) andalso
|
||||||
@ -128,7 +165,9 @@ match_acl(ACL, JID) ->
|
|||||||
is_glob_match(Server, SR) andalso
|
is_glob_match(Server, SR) andalso
|
||||||
is_glob_match(User, UR)
|
is_glob_match(User, UR)
|
||||||
end
|
end
|
||||||
end, ets:lookup(acl, ACL))
|
end,
|
||||||
|
ets:lookup(acl, {ACL, global}) ++
|
||||||
|
ets:lookup(acl, {ACL, Host}))
|
||||||
end.
|
end.
|
||||||
|
|
||||||
is_regexp_match(String, RegExp) ->
|
is_regexp_match(String, RegExp) ->
|
||||||
|
@ -87,14 +87,18 @@ db_init() ->
|
|||||||
mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).
|
mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).
|
||||||
|
|
||||||
load_modules() ->
|
load_modules() ->
|
||||||
|
lists:foreach(
|
||||||
|
fun(Host) ->
|
||||||
case ejabberd_config:get_local_option(modules) of
|
case ejabberd_config:get_local_option(modules) of
|
||||||
undefined ->
|
undefined ->
|
||||||
ok;
|
ok;
|
||||||
Modules ->
|
Modules ->
|
||||||
lists:foreach(fun({Module, Args}) ->
|
lists:foreach(
|
||||||
gen_mod:start_module(Module, Args)
|
fun({Module, Args}) ->
|
||||||
|
gen_mod:start_module(Host, Module, Args)
|
||||||
end, Modules)
|
end, Modules)
|
||||||
end.
|
end
|
||||||
|
end, ?MYHOSTS).
|
||||||
|
|
||||||
|
|
||||||
dump_ports() ->
|
dump_ports() ->
|
||||||
|
@ -165,7 +165,7 @@ remove_user(User, Server) ->
|
|||||||
mnesia:delete({passwd, US})
|
mnesia:delete({passwd, US})
|
||||||
end,
|
end,
|
||||||
mnesia:transaction(F),
|
mnesia:transaction(F),
|
||||||
ejabberd_hooks:run(remove_user, [User, Server]).
|
ejabberd_hooks:run(remove_user, LServer, [User, Server]).
|
||||||
|
|
||||||
remove_user(User, Server, Password) ->
|
remove_user(User, Server, Password) ->
|
||||||
LUser = jlib:nodeprep(User),
|
LUser = jlib:nodeprep(User),
|
||||||
@ -184,7 +184,7 @@ remove_user(User, Server, Password) ->
|
|||||||
end,
|
end,
|
||||||
case mnesia:transaction(F) of
|
case mnesia:transaction(F) of
|
||||||
{atomic, ok} ->
|
{atomic, ok} ->
|
||||||
ejabberd_hooks:run(remove_user, [User, Server]),
|
ejabberd_hooks:run(remove_user, LServer, [User, Server]),
|
||||||
ok;
|
ok;
|
||||||
{atomic, Res} ->
|
{atomic, Res} ->
|
||||||
Res;
|
Res;
|
||||||
|
@ -170,7 +170,7 @@ is_user_exists(User, _Server) ->
|
|||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
remove_user(User, _Server) ->
|
remove_user(User, Server) ->
|
||||||
case jlib:nodeprep(User) of
|
case jlib:nodeprep(User) of
|
||||||
error ->
|
error ->
|
||||||
error;
|
error;
|
||||||
@ -178,10 +178,10 @@ remove_user(User, _Server) ->
|
|||||||
Username = ejabberd_odbc:escape(LUser),
|
Username = ejabberd_odbc:escape(LUser),
|
||||||
catch ejabberd_odbc:sql_query(
|
catch ejabberd_odbc:sql_query(
|
||||||
["delete from users where username='", Username ,"'"]),
|
["delete from users where username='", Username ,"'"]),
|
||||||
ejabberd_hooks:run(remove_user, [User])
|
ejabberd_hooks:run(remove_user, jlib:nameprep(Server), [User])
|
||||||
end.
|
end.
|
||||||
|
|
||||||
remove_user(User, _Server, Password) ->
|
remove_user(User, Server, Password) ->
|
||||||
case jlib:nodeprep(User) of
|
case jlib:nodeprep(User) of
|
||||||
error ->
|
error ->
|
||||||
error;
|
error;
|
||||||
@ -196,7 +196,8 @@ remove_user(User, _Server, Password) ->
|
|||||||
"where username='", Username, "' and password='", Pass, "';"
|
"where username='", Username, "' and password='", Pass, "';"
|
||||||
"commit"]) of
|
"commit"]) of
|
||||||
{selected, ["password"], [{Password}]} ->
|
{selected, ["password"], [{Password}]} ->
|
||||||
ejabberd_hooks:run(remove_user, [User]),
|
ejabberd_hooks:run(remove_user, jlib:nameprep(Server),
|
||||||
|
[User]),
|
||||||
ok;
|
ok;
|
||||||
{selected, ["password"], []} ->
|
{selected, ["password"], []} ->
|
||||||
not_exists;
|
not_exists;
|
||||||
|
@ -340,7 +340,8 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
|||||||
{auth, _ID, set, {U, P, D, R}} ->
|
{auth, _ID, set, {U, P, D, R}} ->
|
||||||
JID = jlib:make_jid(U, StateData#state.server, R),
|
JID = jlib:make_jid(U, StateData#state.server, R),
|
||||||
case (JID /= error) andalso
|
case (JID /= error) andalso
|
||||||
(acl:match_rule(StateData#state.access, JID) == allow) of
|
(acl:match_rule(StateData#state.server,
|
||||||
|
StateData#state.access, JID) == allow) of
|
||||||
true ->
|
true ->
|
||||||
case ejabberd_auth:check_password(
|
case ejabberd_auth:check_password(
|
||||||
U, StateData#state.server, P,
|
U, StateData#state.server, P,
|
||||||
@ -358,6 +359,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
|||||||
change_shaper(StateData, JID),
|
change_shaper(StateData, JID),
|
||||||
{Fs, Ts} = ejabberd_hooks:run_fold(
|
{Fs, Ts} = ejabberd_hooks:run_fold(
|
||||||
roster_get_subscription_lists,
|
roster_get_subscription_lists,
|
||||||
|
StateData#state.server,
|
||||||
{[], []},
|
{[], []},
|
||||||
[U, StateData#state.server]),
|
[U, StateData#state.server]),
|
||||||
LJID = jlib:jid_tolower(
|
LJID = jlib:jid_tolower(
|
||||||
@ -651,7 +653,8 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
|
|||||||
U = StateData#state.user,
|
U = StateData#state.user,
|
||||||
R = StateData#state.resource,
|
R = StateData#state.resource,
|
||||||
JID = StateData#state.jid,
|
JID = StateData#state.jid,
|
||||||
case acl:match_rule(StateData#state.access, JID) of
|
case acl:match_rule(StateData#state.server,
|
||||||
|
StateData#state.access, JID) of
|
||||||
allow ->
|
allow ->
|
||||||
?INFO_MSG("(~w) Opened session for ~s",
|
?INFO_MSG("(~w) Opened session for ~s",
|
||||||
[StateData#state.socket,
|
[StateData#state.socket,
|
||||||
@ -663,6 +666,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
|
|||||||
change_shaper(StateData, JID),
|
change_shaper(StateData, JID),
|
||||||
{Fs, Ts} = ejabberd_hooks:run_fold(
|
{Fs, Ts} = ejabberd_hooks:run_fold(
|
||||||
roster_get_subscription_lists,
|
roster_get_subscription_lists,
|
||||||
|
StateData#state.server,
|
||||||
{[], []},
|
{[], []},
|
||||||
[U, StateData#state.server]),
|
[U, StateData#state.server]),
|
||||||
LJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
|
LJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
|
||||||
@ -764,6 +768,7 @@ session_established({xmlstreamelement, El}, StateData) ->
|
|||||||
_ ->
|
_ ->
|
||||||
ejabberd_hooks:run(
|
ejabberd_hooks:run(
|
||||||
user_send_packet,
|
user_send_packet,
|
||||||
|
Server,
|
||||||
[FromJID, ToJID, NewEl]),
|
[FromJID, ToJID, NewEl]),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
FromJID, ToJID, NewEl),
|
FromJID, ToJID, NewEl),
|
||||||
@ -772,6 +777,7 @@ session_established({xmlstreamelement, El}, StateData) ->
|
|||||||
end;
|
end;
|
||||||
"message" ->
|
"message" ->
|
||||||
ejabberd_hooks:run(user_send_packet,
|
ejabberd_hooks:run(user_send_packet,
|
||||||
|
Server,
|
||||||
[FromJID, ToJID, NewEl]),
|
[FromJID, ToJID, NewEl]),
|
||||||
ejabberd_router:route(FromJID, ToJID, NewEl),
|
ejabberd_router:route(FromJID, ToJID, NewEl),
|
||||||
StateData;
|
StateData;
|
||||||
@ -983,6 +989,7 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
|
|||||||
Text = xml:element_to_string(FixedPacket),
|
Text = xml:element_to_string(FixedPacket),
|
||||||
send_text(StateData, Text),
|
send_text(StateData, Text),
|
||||||
ejabberd_hooks:run(user_receive_packet,
|
ejabberd_hooks:run(user_receive_packet,
|
||||||
|
StateData#state.server,
|
||||||
[StateData#state.jid, From, To, FixedPacket]),
|
[StateData#state.jid, From, To, FixedPacket]),
|
||||||
{next_state, StateName, NewState};
|
{next_state, StateName, NewState};
|
||||||
true ->
|
true ->
|
||||||
@ -1055,7 +1062,8 @@ terminate(_Reason, StateName, StateData) ->
|
|||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
change_shaper(StateData, JID) ->
|
change_shaper(StateData, JID) ->
|
||||||
Shaper = acl:match_rule(StateData#state.shaper, JID),
|
Shaper = acl:match_rule(StateData#state.server,
|
||||||
|
StateData#state.shaper, JID),
|
||||||
ejabberd_receiver:change_shaper(StateData#state.receiver, Shaper).
|
ejabberd_receiver:change_shaper(StateData#state.receiver, Shaper).
|
||||||
|
|
||||||
send_text(StateData, Text) ->
|
send_text(StateData, Text) ->
|
||||||
@ -1208,6 +1216,7 @@ presence_update(From, Packet, StateData) ->
|
|||||||
if
|
if
|
||||||
FromUnavail ->
|
FromUnavail ->
|
||||||
ejabberd_hooks:run(user_available_hook,
|
ejabberd_hooks:run(user_available_hook,
|
||||||
|
StateData#state.server,
|
||||||
[StateData#state.jid]),
|
[StateData#state.jid]),
|
||||||
resend_offline_messages(StateData),
|
resend_offline_messages(StateData),
|
||||||
presence_broadcast_first(
|
presence_broadcast_first(
|
||||||
@ -1248,21 +1257,25 @@ presence_track(From, To, Packet, StateData) ->
|
|||||||
"subscribe" ->
|
"subscribe" ->
|
||||||
ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
|
ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
|
||||||
ejabberd_hooks:run(roster_out_subscription,
|
ejabberd_hooks:run(roster_out_subscription,
|
||||||
|
Server,
|
||||||
[User, Server, To, subscribe]),
|
[User, Server, To, subscribe]),
|
||||||
StateData;
|
StateData;
|
||||||
"subscribed" ->
|
"subscribed" ->
|
||||||
ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
|
ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
|
||||||
ejabberd_hooks:run(roster_out_subscription,
|
ejabberd_hooks:run(roster_out_subscription,
|
||||||
|
Server,
|
||||||
[User, Server, To, subscribed]),
|
[User, Server, To, subscribed]),
|
||||||
StateData;
|
StateData;
|
||||||
"unsubscribe" ->
|
"unsubscribe" ->
|
||||||
ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
|
ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
|
||||||
ejabberd_hooks:run(roster_out_subscription,
|
ejabberd_hooks:run(roster_out_subscription,
|
||||||
|
Server,
|
||||||
[User, Server, To, unsubscribe]),
|
[User, Server, To, unsubscribe]),
|
||||||
StateData;
|
StateData;
|
||||||
"unsubscribed" ->
|
"unsubscribed" ->
|
||||||
ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
|
ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
|
||||||
ejabberd_hooks:run(roster_out_subscription,
|
ejabberd_hooks:run(roster_out_subscription,
|
||||||
|
Server,
|
||||||
[User, Server, To, unsubscribed]),
|
[User, Server, To, unsubscribed]),
|
||||||
StateData;
|
StateData;
|
||||||
"error" ->
|
"error" ->
|
||||||
@ -1505,7 +1518,9 @@ process_privacy_iq(From, To,
|
|||||||
resend_offline_messages(#state{user = User,
|
resend_offline_messages(#state{user = User,
|
||||||
server = Server,
|
server = Server,
|
||||||
privacy_list = PrivList} = StateData) ->
|
privacy_list = PrivList} = StateData) ->
|
||||||
case ejabberd_hooks:run_fold(resend_offline_messages_hook, [],
|
case ejabberd_hooks:run_fold(resend_offline_messages_hook,
|
||||||
|
Server,
|
||||||
|
[],
|
||||||
[User, Server]) of
|
[User, Server]) of
|
||||||
Rs when list(Rs) ->
|
Rs when list(Rs) ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% File : ejabberd_config.erl
|
%%% File : ejabberd_config.erl
|
||||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||||
%%% Purpose :
|
%%% Purpose : Load config file
|
||||||
%%% Created : 14 Dec 2002 by Alexey Shchepin <alexey@sevcom.net>
|
%%% Created : 14 Dec 2002 by Alexey Shchepin <alexey@sevcom.net>
|
||||||
%%% Id : $Id$
|
%%% Id : $Id$
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
@ -19,12 +19,12 @@
|
|||||||
-record(config, {key, value}).
|
-record(config, {key, value}).
|
||||||
-record(local_config, {key, value}).
|
-record(local_config, {key, value}).
|
||||||
-record(state, {opts = [],
|
-record(state, {opts = [],
|
||||||
|
hosts = [],
|
||||||
override_local = false,
|
override_local = false,
|
||||||
override_global = false,
|
override_global = false,
|
||||||
override_acls = false}).
|
override_acls = false}).
|
||||||
|
|
||||||
start() ->
|
start() ->
|
||||||
%ets:new(ejabberd_config, [named_table, public]),
|
|
||||||
mnesia:create_table(config,
|
mnesia:create_table(config,
|
||||||
[{disc_copies, [node()]},
|
[{disc_copies, [node()]},
|
||||||
{attributes, record_info(fields, config)}]),
|
{attributes, record_info(fields, config)}]),
|
||||||
@ -34,8 +34,6 @@ start() ->
|
|||||||
{local_content, true},
|
{local_content, true},
|
||||||
{attributes, record_info(fields, local_config)}]),
|
{attributes, record_info(fields, local_config)}]),
|
||||||
mnesia:add_table_copy(local_config, node(), ram_copies),
|
mnesia:add_table_copy(local_config, node(), ram_copies),
|
||||||
|
|
||||||
%% mremond: Config file can be configured from the command line
|
|
||||||
Config = case application:get_env(config) of
|
Config = case application:get_env(config) of
|
||||||
{ok, Path} -> Path;
|
{ok, Path} -> Path;
|
||||||
undefined ->
|
undefined ->
|
||||||
@ -52,13 +50,38 @@ start() ->
|
|||||||
load_file(File) ->
|
load_file(File) ->
|
||||||
case file:consult(File) of
|
case file:consult(File) of
|
||||||
{ok, Terms} ->
|
{ok, Terms} ->
|
||||||
Res = lists:foldl(fun process_term/2, #state{}, Terms),
|
State = lists:foldl(fun search_hosts/2, #state{}, Terms),
|
||||||
|
Res = lists:foldl(fun process_term/2, State, Terms),
|
||||||
set_opts(Res);
|
set_opts(Res);
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
?ERROR_MSG("Can't load config file ~p: ~p", [File, Reason]),
|
?ERROR_MSG("Can't load config file ~p: ~p", [File, Reason]),
|
||||||
exit(file:format_error(Reason))
|
exit(file:format_error(Reason))
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
search_hosts(Term, State) ->
|
||||||
|
case Term of
|
||||||
|
{host, Host} ->
|
||||||
|
if
|
||||||
|
State#state.hosts == [] ->
|
||||||
|
add_option(hosts, [Host], State#state{hosts = [Host]});
|
||||||
|
true ->
|
||||||
|
?ERROR_MSG("Can't load config file: "
|
||||||
|
"too many hosts definitions", []),
|
||||||
|
exit("too many hosts definitions")
|
||||||
|
end;
|
||||||
|
{hosts, Hosts} ->
|
||||||
|
if
|
||||||
|
State#state.hosts == [] ->
|
||||||
|
add_option(hosts, Hosts, State#state{hosts = Hosts});
|
||||||
|
true ->
|
||||||
|
?ERROR_MSG("Can't load config file: "
|
||||||
|
"too many hosts definitions", []),
|
||||||
|
exit("too many hosts definitions")
|
||||||
|
end;
|
||||||
|
_ ->
|
||||||
|
State
|
||||||
|
end.
|
||||||
|
|
||||||
process_term(Term, State) ->
|
process_term(Term, State) ->
|
||||||
case Term of
|
case Term of
|
||||||
override_global ->
|
override_global ->
|
||||||
@ -68,20 +91,40 @@ process_term(Term, State) ->
|
|||||||
override_acls ->
|
override_acls ->
|
||||||
State#state{override_acls = true};
|
State#state{override_acls = true};
|
||||||
{acl, ACLName, ACLData} ->
|
{acl, ACLName, ACLData} ->
|
||||||
State#state{opts =
|
process_host_term(Term, global, State);
|
||||||
[acl:to_record(ACLName, ACLData) | State#state.opts]};
|
|
||||||
{access, RuleName, Rules} ->
|
{access, RuleName, Rules} ->
|
||||||
State#state{opts = [#config{key = {access, RuleName},
|
process_host_term(Term, global, State);
|
||||||
|
{shaper, Name, Data} ->
|
||||||
|
lists:foldl(fun(Host, S) -> process_host_term(Term, Host, S) end,
|
||||||
|
State, State#state.hosts);
|
||||||
|
{host, Host} ->
|
||||||
|
State;
|
||||||
|
{hosts, Hosts} ->
|
||||||
|
State;
|
||||||
|
{Opt, Val} ->
|
||||||
|
lists:foldl(fun(Host, S) -> process_host_term(Term, Host, S) end,
|
||||||
|
State, State#state.hosts)
|
||||||
|
end.
|
||||||
|
|
||||||
|
process_host_term(Term, Host, State) ->
|
||||||
|
case Term of
|
||||||
|
{acl, ACLName, ACLData} ->
|
||||||
|
State#state{opts =
|
||||||
|
[acl:to_record(Host, ACLName, ACLData) | State#state.opts]};
|
||||||
|
{access, RuleName, Rules} ->
|
||||||
|
State#state{opts = [#config{key = {access, RuleName, Host},
|
||||||
value = Rules} |
|
value = Rules} |
|
||||||
State#state.opts]};
|
State#state.opts]};
|
||||||
{shaper, Name, Data} ->
|
{shaper, Name, Data} ->
|
||||||
State#state{opts = [#config{key = {shaper, Name},
|
State#state{opts = [#config{key = {shaper, Name, Host},
|
||||||
value = Data} |
|
value = Data} |
|
||||||
State#state.opts]};
|
State#state.opts]};
|
||||||
{host, Host} ->
|
{host, Host} ->
|
||||||
add_option(hosts, [Host], State);
|
State;
|
||||||
|
{hosts, Hosts} ->
|
||||||
|
State;
|
||||||
{Opt, Val} ->
|
{Opt, Val} ->
|
||||||
add_option(Opt, Val, State)
|
add_option({Opt, Host}, Val, State)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
add_option(Opt, Val, State) ->
|
add_option(Opt, Val, State) ->
|
||||||
|
@ -16,7 +16,11 @@
|
|||||||
add/4,
|
add/4,
|
||||||
delete/4,
|
delete/4,
|
||||||
run/2,
|
run/2,
|
||||||
run_fold/3]).
|
run_fold/3,
|
||||||
|
add/5,
|
||||||
|
delete/5,
|
||||||
|
run/3,
|
||||||
|
run_fold/4]).
|
||||||
|
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
-export([init/1,
|
-export([init/1,
|
||||||
@ -37,13 +41,22 @@ start_link() ->
|
|||||||
gen_server:start_link({local, ejabberd_hooks}, ejabberd_hooks, [], []).
|
gen_server:start_link({local, ejabberd_hooks}, ejabberd_hooks, [], []).
|
||||||
|
|
||||||
add(Hook, Module, Function, Seq) ->
|
add(Hook, Module, Function, Seq) ->
|
||||||
gen_server:call(ejabberd_hooks, {add, Hook, Module, Function, Seq}).
|
add(Hook, global, Module, Function, Seq).
|
||||||
|
|
||||||
|
add(Hook, Host, Module, Function, Seq) ->
|
||||||
|
gen_server:call(ejabberd_hooks, {add, Hook, Host, Module, Function, Seq}).
|
||||||
|
|
||||||
delete(Hook, Module, Function, Seq) ->
|
delete(Hook, Module, Function, Seq) ->
|
||||||
gen_server:call(ejabberd_hooks, {delete, Hook, Module, Function, Seq}).
|
delete(Hook, global, Module, Function, Seq).
|
||||||
|
|
||||||
|
delete(Hook, Host, Module, Function, Seq) ->
|
||||||
|
gen_server:call(ejabberd_hooks, {delete, Hook, Host, Module, Function, Seq}).
|
||||||
|
|
||||||
run(Hook, Args) ->
|
run(Hook, Args) ->
|
||||||
case ets:lookup(hooks, Hook) of
|
run(Hook, global, Args).
|
||||||
|
|
||||||
|
run(Hook, Host, Args) ->
|
||||||
|
case ets:lookup(hooks, {Hook, Host}) of
|
||||||
[{_, Ls}] ->
|
[{_, Ls}] ->
|
||||||
run1(Ls, Hook, Args);
|
run1(Ls, Hook, Args);
|
||||||
[] ->
|
[] ->
|
||||||
@ -51,7 +64,10 @@ run(Hook, Args) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
run_fold(Hook, Val, Args) ->
|
run_fold(Hook, Val, Args) ->
|
||||||
case ets:lookup(hooks, Hook) of
|
run_fold(Hook, global, Val, Args).
|
||||||
|
|
||||||
|
run_fold(Hook, Host, Val, Args) ->
|
||||||
|
case ets:lookup(hooks, {Hook, Host}) of
|
||||||
[{_, Ls}] ->
|
[{_, Ls}] ->
|
||||||
run_fold1(Ls, Hook, Val, Args);
|
run_fold1(Ls, Hook, Val, Args);
|
||||||
[] ->
|
[] ->
|
||||||
@ -82,8 +98,8 @@ init([]) ->
|
|||||||
%% {stop, Reason, Reply, State} | (terminate/2 is called)
|
%% {stop, Reason, Reply, State} | (terminate/2 is called)
|
||||||
%% {stop, Reason, State} (terminate/2 is called)
|
%% {stop, Reason, State} (terminate/2 is called)
|
||||||
%%----------------------------------------------------------------------
|
%%----------------------------------------------------------------------
|
||||||
handle_call({add, Hook, Module, Function, Seq}, From, State) ->
|
handle_call({add, Hook, Host, Module, Function, Seq}, From, State) ->
|
||||||
Reply = case ets:lookup(hooks, Hook) of
|
Reply = case ets:lookup(hooks, {Hook, Host}) of
|
||||||
[{_, Ls}] ->
|
[{_, Ls}] ->
|
||||||
El = {Seq, Module, Function},
|
El = {Seq, Module, Function},
|
||||||
case lists:member(El, Ls) of
|
case lists:member(El, Ls) of
|
||||||
@ -91,20 +107,20 @@ handle_call({add, Hook, Module, Function, Seq}, From, State) ->
|
|||||||
ok;
|
ok;
|
||||||
false ->
|
false ->
|
||||||
NewLs = lists:merge(Ls, [El]),
|
NewLs = lists:merge(Ls, [El]),
|
||||||
ets:insert(hooks, {Hook, NewLs}),
|
ets:insert(hooks, {{Hook, Host}, NewLs}),
|
||||||
ok
|
ok
|
||||||
end;
|
end;
|
||||||
[] ->
|
[] ->
|
||||||
NewLs = [{Seq, Module, Function}],
|
NewLs = [{Seq, Module, Function}],
|
||||||
ets:insert(hooks, {Hook, NewLs}),
|
ets:insert(hooks, {{Hook, Host}, NewLs}),
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
{reply, Reply, State};
|
{reply, Reply, State};
|
||||||
handle_call({delete, Hook, Module, Function, Seq}, From, State) ->
|
handle_call({delete, Hook, Host, Module, Function, Seq}, From, State) ->
|
||||||
Reply = case ets:lookup(hooks, Hook) of
|
Reply = case ets:lookup(hooks, {Hook, Host}) of
|
||||||
[{_, Ls}] ->
|
[{_, Ls}] ->
|
||||||
NewLs = lists:delete({Seq, Module, Function}, Ls),
|
NewLs = lists:delete({Seq, Module, Function}, Ls),
|
||||||
ets:insert(hooks, {Hook, NewLs}),
|
ets:insert(hooks, {{Hook, Host}, NewLs}),
|
||||||
ok;
|
ok;
|
||||||
[] ->
|
[] ->
|
||||||
ok
|
ok
|
||||||
|
@ -13,9 +13,9 @@
|
|||||||
-export([start_link/0, init/0]).
|
-export([start_link/0, init/0]).
|
||||||
|
|
||||||
-export([route/3,
|
-export([route/3,
|
||||||
register_iq_handler/3,
|
|
||||||
register_iq_handler/4,
|
register_iq_handler/4,
|
||||||
unregister_iq_handler/1,
|
register_iq_handler/5,
|
||||||
|
unregister_iq_handler/2,
|
||||||
refresh_iq_handlers/0,
|
refresh_iq_handlers/0,
|
||||||
bounce_resource_packet/3
|
bounce_resource_packet/3
|
||||||
]).
|
]).
|
||||||
@ -33,11 +33,11 @@ start_link() ->
|
|||||||
init() ->
|
init() ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun(Host) ->
|
fun(Host) ->
|
||||||
ejabberd_router:register_route(Host, {apply, ?MODULE, route})
|
ejabberd_router:register_route(Host, {apply, ?MODULE, route}),
|
||||||
|
ejabberd_hooks:add(local_send_to_resource_hook, Host,
|
||||||
|
?MODULE, bounce_resource_packet, 100)
|
||||||
end, ?MYHOSTS),
|
end, ?MYHOSTS),
|
||||||
catch ets:new(?IQTABLE, [named_table, public]),
|
catch ets:new(?IQTABLE, [named_table, public]),
|
||||||
ejabberd_hooks:add(local_send_to_resource_hook,
|
|
||||||
?MODULE, bounce_resource_packet, 100),
|
|
||||||
loop().
|
loop().
|
||||||
|
|
||||||
loop() ->
|
loop() ->
|
||||||
@ -51,32 +51,32 @@ loop() ->
|
|||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
loop();
|
loop();
|
||||||
{register_iq_handler, XMLNS, Module, Function} ->
|
{register_iq_handler, Host, XMLNS, Module, Function} ->
|
||||||
ets:insert(?IQTABLE, {XMLNS, Module, Function}),
|
ets:insert(?IQTABLE, {{XMLNS, Host}, Module, Function}),
|
||||||
catch mod_disco:register_feature(XMLNS),
|
catch mod_disco:register_feature(Host, XMLNS),
|
||||||
loop();
|
loop();
|
||||||
{register_iq_handler, XMLNS, Module, Function, Opts} ->
|
{register_iq_handler, Host, XMLNS, Module, Function, Opts} ->
|
||||||
ets:insert(?IQTABLE, {XMLNS, Module, Function, Opts}),
|
ets:insert(?IQTABLE, {{XMLNS, Host}, Module, Function, Opts}),
|
||||||
catch mod_disco:register_feature(XMLNS),
|
catch mod_disco:register_feature(Host, XMLNS),
|
||||||
loop();
|
loop();
|
||||||
{unregister_iq_handler, XMLNS} ->
|
{unregister_iq_handler, Host, XMLNS} ->
|
||||||
case ets:lookup(?IQTABLE, XMLNS) of
|
case ets:lookup(?IQTABLE, {XMLNS, Host}) of
|
||||||
[{_, Module, Function, Opts}] ->
|
[{_, Module, Function, Opts}] ->
|
||||||
gen_iq_handler:stop_iq_handler(Module, Function, Opts);
|
gen_iq_handler:stop_iq_handler(Module, Function, Opts);
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
ets:delete(?IQTABLE, XMLNS),
|
ets:delete(?IQTABLE, {XMLNS, Host}),
|
||||||
catch mod_disco:unregister_feature(XMLNS),
|
catch mod_disco:unregister_feature(Host, XMLNS),
|
||||||
loop();
|
loop();
|
||||||
refresh_iq_handlers ->
|
refresh_iq_handlers ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun(T) ->
|
fun(T) ->
|
||||||
case T of
|
case T of
|
||||||
{XMLNS, _Module, _Function, _Opts} ->
|
{{XMLNS, Host}, _Module, _Function, _Opts} ->
|
||||||
catch mod_disco:register_feature(XMLNS);
|
catch mod_disco:register_feature(Host, XMLNS);
|
||||||
{XMLNS, _Module, _Function} ->
|
{{XMLNS, Host}, _Module, _Function} ->
|
||||||
catch mod_disco:register_feature(XMLNS);
|
catch mod_disco:register_feature(Host, XMLNS);
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end
|
end
|
||||||
@ -112,6 +112,7 @@ do_route(From, To, Packet) ->
|
|||||||
"result" -> ok;
|
"result" -> ok;
|
||||||
_ ->
|
_ ->
|
||||||
ejabberd_hooks:run(local_send_to_resource_hook,
|
ejabberd_hooks:run(local_send_to_resource_hook,
|
||||||
|
To#jid.lserver,
|
||||||
[From, To, Packet])
|
[From, To, Packet])
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
@ -120,7 +121,8 @@ process_iq(From, To, Packet) ->
|
|||||||
IQ = jlib:iq_query_info(Packet),
|
IQ = jlib:iq_query_info(Packet),
|
||||||
case IQ of
|
case IQ of
|
||||||
#iq{xmlns = XMLNS} ->
|
#iq{xmlns = XMLNS} ->
|
||||||
case ets:lookup(?IQTABLE, XMLNS) of
|
Host = To#jid.lserver,
|
||||||
|
case ets:lookup(?IQTABLE, {XMLNS, Host}) of
|
||||||
[{_, Module, Function}] ->
|
[{_, Module, Function}] ->
|
||||||
ResIQ = Module:Function(From, To, IQ),
|
ResIQ = Module:Function(From, To, IQ),
|
||||||
if
|
if
|
||||||
@ -131,7 +133,7 @@ process_iq(From, To, Packet) ->
|
|||||||
ok
|
ok
|
||||||
end;
|
end;
|
||||||
[{_, Module, Function, Opts}] ->
|
[{_, Module, Function, Opts}] ->
|
||||||
gen_iq_handler:handle(Module, Function, Opts,
|
gen_iq_handler:handle(Host, Module, Function, Opts,
|
||||||
From, To, IQ);
|
From, To, IQ);
|
||||||
[] ->
|
[] ->
|
||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
@ -155,14 +157,14 @@ route(From, To, Packet) ->
|
|||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
register_iq_handler(XMLNS, Module, Fun) ->
|
register_iq_handler(Host, XMLNS, Module, Fun) ->
|
||||||
ejabberd_local ! {register_iq_handler, XMLNS, Module, Fun}.
|
ejabberd_local ! {register_iq_handler, Host, XMLNS, Module, Fun}.
|
||||||
|
|
||||||
register_iq_handler(XMLNS, Module, Fun, Opts) ->
|
register_iq_handler(Host, XMLNS, Module, Fun, Opts) ->
|
||||||
ejabberd_local ! {register_iq_handler, XMLNS, Module, Fun, Opts}.
|
ejabberd_local ! {register_iq_handler, Host, XMLNS, Module, Fun, Opts}.
|
||||||
|
|
||||||
unregister_iq_handler(XMLNS) ->
|
unregister_iq_handler(Host, XMLNS) ->
|
||||||
ejabberd_local ! {unregister_iq_handler, XMLNS}.
|
ejabberd_local ! {unregister_iq_handler, Host, XMLNS}.
|
||||||
|
|
||||||
refresh_iq_handlers() ->
|
refresh_iq_handlers() ->
|
||||||
ejabberd_local ! refresh_iq_handlers.
|
ejabberd_local ! refresh_iq_handlers.
|
||||||
|
@ -148,7 +148,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
|
|||||||
Key, StateData#state.streamid}),
|
Key, StateData#state.streamid}),
|
||||||
Conns = ?DICT:store({LFrom, LTo}, wait_for_verification,
|
Conns = ?DICT:store({LFrom, LTo}, wait_for_verification,
|
||||||
StateData#state.connections),
|
StateData#state.connections),
|
||||||
change_shaper(StateData, jlib:make_jid("", LFrom, "")),
|
change_shaper(StateData, LTo, jlib:make_jid("", LFrom, "")),
|
||||||
{next_state,
|
{next_state,
|
||||||
stream_established,
|
stream_established,
|
||||||
StateData#state{connections = Conns,
|
StateData#state{connections = Conns,
|
||||||
@ -326,8 +326,8 @@ send_element(Socket, El) ->
|
|||||||
send_text(Socket, xml:element_to_string(El)).
|
send_text(Socket, xml:element_to_string(El)).
|
||||||
|
|
||||||
|
|
||||||
change_shaper(StateData, JID) ->
|
change_shaper(StateData, Host, JID) ->
|
||||||
Shaper = acl:match_rule(StateData#state.shaper, JID),
|
Shaper = acl:match_rule(Host, StateData#state.shaper, JID),
|
||||||
ejabberd_receiver:change_shaper(StateData#state.receiver, Shaper).
|
ejabberd_receiver:change_shaper(StateData#state.receiver, Shaper).
|
||||||
|
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ handle_info({send_element, El}, StateName, StateData) ->
|
|||||||
send_element(StateData, El),
|
send_element(StateData, El),
|
||||||
{next_state, StateName, StateData};
|
{next_state, StateName, StateData};
|
||||||
handle_info({route, From, To, Packet}, StateName, StateData) ->
|
handle_info({route, From, To, Packet}, StateName, StateData) ->
|
||||||
case acl:match_rule(StateData#state.access, From) of
|
case acl:match_rule(global, StateData#state.access, From) of
|
||||||
allow ->
|
allow ->
|
||||||
{xmlelement, Name, Attrs, Els} = Packet,
|
{xmlelement, Name, Attrs, Els} = Packet,
|
||||||
Attrs2 = jlib:replace_from_to_attrs(jlib:jid_to_string(From),
|
Attrs2 = jlib:replace_from_to_attrs(jlib:jid_to_string(From),
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
dirty_get_sessions_list/0,
|
dirty_get_sessions_list/0,
|
||||||
dirty_get_my_sessions_list/0,
|
dirty_get_my_sessions_list/0,
|
||||||
get_vh_session_list/1,
|
get_vh_session_list/1,
|
||||||
register_iq_handler/3,
|
|
||||||
register_iq_handler/4,
|
register_iq_handler/4,
|
||||||
unregister_iq_handler/1
|
register_iq_handler/5,
|
||||||
|
unregister_iq_handler/2
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
@ -49,10 +49,13 @@ init() ->
|
|||||||
mnesia:add_table_index(presence, us),
|
mnesia:add_table_index(presence, us),
|
||||||
mnesia:subscribe(system),
|
mnesia:subscribe(system),
|
||||||
ets:new(sm_iqtable, [named_table]),
|
ets:new(sm_iqtable, [named_table]),
|
||||||
ejabberd_hooks:add(offline_message_hook,
|
lists:foreach(
|
||||||
|
fun(Host) ->
|
||||||
|
ejabberd_hooks:add(offline_message_hook, Host,
|
||||||
ejabberd_sm, bounce_offline_message, 100),
|
ejabberd_sm, bounce_offline_message, 100),
|
||||||
ejabberd_hooks:add(remove_user,
|
ejabberd_hooks:add(remove_user, Host,
|
||||||
ejabberd_sm, disconnect_removed_user, 100),
|
ejabberd_sm, disconnect_removed_user, 100)
|
||||||
|
end, ?MYHOSTS),
|
||||||
loop().
|
loop().
|
||||||
|
|
||||||
loop() ->
|
loop() ->
|
||||||
@ -69,20 +72,20 @@ loop() ->
|
|||||||
{mnesia_system_event, {mnesia_down, Node}} ->
|
{mnesia_system_event, {mnesia_down, Node}} ->
|
||||||
clean_table_from_bad_node(Node),
|
clean_table_from_bad_node(Node),
|
||||||
loop();
|
loop();
|
||||||
{register_iq_handler, XMLNS, Module, Function} ->
|
{register_iq_handler, Host, XMLNS, Module, Function} ->
|
||||||
ets:insert(sm_iqtable, {XMLNS, Module, Function}),
|
ets:insert(sm_iqtable, {{XMLNS, Host}, Module, Function}),
|
||||||
loop();
|
loop();
|
||||||
{register_iq_handler, XMLNS, Module, Function, Opts} ->
|
{register_iq_handler, Host, XMLNS, Module, Function, Opts} ->
|
||||||
ets:insert(sm_iqtable, {XMLNS, Module, Function, Opts}),
|
ets:insert(sm_iqtable, {{XMLNS, Host}, Module, Function, Opts}),
|
||||||
loop();
|
loop();
|
||||||
{unregister_iq_handler, XMLNS} ->
|
{unregister_iq_handler, Host, XMLNS} ->
|
||||||
case ets:lookup(sm_iqtable, XMLNS) of
|
case ets:lookup(sm_iqtable, {XMLNS, Host}) of
|
||||||
[{_, Module, Function, Opts}] ->
|
[{_, Module, Function, Opts}] ->
|
||||||
gen_iq_handler:stop_iq_handler(Module, Function, Opts);
|
gen_iq_handler:stop_iq_handler(Module, Function, Opts);
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
ets:delete(sm_iqtable, XMLNS),
|
ets:delete(sm_iqtable, {XMLNS, Host}),
|
||||||
loop();
|
loop();
|
||||||
_ ->
|
_ ->
|
||||||
loop()
|
loop()
|
||||||
@ -170,24 +173,28 @@ do_route(From, To, Packet) ->
|
|||||||
"subscribe" ->
|
"subscribe" ->
|
||||||
{ejabberd_hooks:run_fold(
|
{ejabberd_hooks:run_fold(
|
||||||
roster_in_subscription,
|
roster_in_subscription,
|
||||||
|
LServer,
|
||||||
false,
|
false,
|
||||||
[User, Server, From, subscribe]),
|
[User, Server, From, subscribe]),
|
||||||
true};
|
true};
|
||||||
"subscribed" ->
|
"subscribed" ->
|
||||||
{ejabberd_hooks:run_fold(
|
{ejabberd_hooks:run_fold(
|
||||||
roster_in_subscription,
|
roster_in_subscription,
|
||||||
|
LServer,
|
||||||
false,
|
false,
|
||||||
[User, Server, From, subscribed]),
|
[User, Server, From, subscribed]),
|
||||||
true};
|
true};
|
||||||
"unsubscribe" ->
|
"unsubscribe" ->
|
||||||
{ejabberd_hooks:run_fold(
|
{ejabberd_hooks:run_fold(
|
||||||
roster_in_subscription,
|
roster_in_subscription,
|
||||||
|
LServer,
|
||||||
false,
|
false,
|
||||||
[User, Server, From, unsubscribe]),
|
[User, Server, From, unsubscribe]),
|
||||||
true};
|
true};
|
||||||
"unsubscribed" ->
|
"unsubscribed" ->
|
||||||
{ejabberd_hooks:run_fold(
|
{ejabberd_hooks:run_fold(
|
||||||
roster_in_subscription,
|
roster_in_subscription,
|
||||||
|
LServer,
|
||||||
false,
|
false,
|
||||||
[User, Server, From, unsubscribed]),
|
[User, Server, From, unsubscribed]),
|
||||||
true};
|
true};
|
||||||
@ -220,6 +227,7 @@ do_route(From, To, Packet) ->
|
|||||||
true ->
|
true ->
|
||||||
ejabberd_hooks:run(
|
ejabberd_hooks:run(
|
||||||
offline_subscription_hook,
|
offline_subscription_hook,
|
||||||
|
LServer,
|
||||||
[From, To, Packet]);
|
[From, To, Packet]);
|
||||||
_ ->
|
_ ->
|
||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
@ -298,6 +306,7 @@ route_message(From, To, Packet) ->
|
|||||||
case ejabberd_auth:is_user_exists(LUser, LServer) of
|
case ejabberd_auth:is_user_exists(LUser, LServer) of
|
||||||
true ->
|
true ->
|
||||||
ejabberd_hooks:run(offline_message_hook,
|
ejabberd_hooks:run(offline_message_hook,
|
||||||
|
LServer,
|
||||||
[From, To, Packet]);
|
[From, To, Packet]);
|
||||||
_ ->
|
_ ->
|
||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
@ -354,7 +363,8 @@ unset_presence(User, Server, Resource, Status) ->
|
|||||||
mnesia:delete({presence, USR})
|
mnesia:delete({presence, USR})
|
||||||
end,
|
end,
|
||||||
mnesia:transaction(F),
|
mnesia:transaction(F),
|
||||||
ejabberd_hooks:run(unset_presence_hook, [User, Server, Resource, Status]).
|
ejabberd_hooks:run(unset_presence_hook, jlib:nameprep(Server),
|
||||||
|
[User, Server, Resource, Status]).
|
||||||
|
|
||||||
get_user_present_resources(LUser, LServer) ->
|
get_user_present_resources(LUser, LServer) ->
|
||||||
US = {LUser, LServer},
|
US = {LUser, LServer},
|
||||||
@ -392,7 +402,8 @@ process_iq(From, To, Packet) ->
|
|||||||
IQ = jlib:iq_query_info(Packet),
|
IQ = jlib:iq_query_info(Packet),
|
||||||
case IQ of
|
case IQ of
|
||||||
#iq{xmlns = XMLNS} ->
|
#iq{xmlns = XMLNS} ->
|
||||||
case ets:lookup(sm_iqtable, XMLNS) of
|
Host = To#jid.lserver,
|
||||||
|
case ets:lookup(sm_iqtable, {XMLNS, Host}) of
|
||||||
[{_, Module, Function}] ->
|
[{_, Module, Function}] ->
|
||||||
ResIQ = Module:Function(From, To, IQ),
|
ResIQ = Module:Function(From, To, IQ),
|
||||||
if
|
if
|
||||||
@ -403,7 +414,7 @@ process_iq(From, To, Packet) ->
|
|||||||
ok
|
ok
|
||||||
end;
|
end;
|
||||||
[{_, Module, Function, Opts}] ->
|
[{_, Module, Function, Opts}] ->
|
||||||
gen_iq_handler:handle(Module, Function, Opts,
|
gen_iq_handler:handle(Host, Module, Function, Opts,
|
||||||
From, To, IQ);
|
From, To, IQ);
|
||||||
[] ->
|
[] ->
|
||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
@ -418,14 +429,14 @@ process_iq(From, To, Packet) ->
|
|||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
register_iq_handler(XMLNS, Module, Fun) ->
|
register_iq_handler(Host, XMLNS, Module, Fun) ->
|
||||||
ejabberd_sm ! {register_iq_handler, XMLNS, Module, Fun}.
|
ejabberd_sm ! {register_iq_handler, Host, XMLNS, Module, Fun}.
|
||||||
|
|
||||||
register_iq_handler(XMLNS, Module, Fun, Opts) ->
|
register_iq_handler(Host, XMLNS, Module, Fun, Opts) ->
|
||||||
ejabberd_sm ! {register_iq_handler, XMLNS, Module, Fun, Opts}.
|
ejabberd_sm ! {register_iq_handler, Host, XMLNS, Module, Fun, Opts}.
|
||||||
|
|
||||||
unregister_iq_handler(XMLNS) ->
|
unregister_iq_handler(Host, XMLNS) ->
|
||||||
ejabberd_sm ! {unregister_iq_handler, XMLNS}.
|
ejabberd_sm ! {unregister_iq_handler, Host, XMLNS}.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,33 +11,33 @@
|
|||||||
-vsn('$Revision$ ').
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
-export([start/0,
|
-export([start/0,
|
||||||
start_link/2,
|
start_link/3,
|
||||||
add_iq_handler/5,
|
add_iq_handler/6,
|
||||||
remove_iq_handler/2,
|
remove_iq_handler/3,
|
||||||
stop_iq_handler/3,
|
stop_iq_handler/3,
|
||||||
handle/6,
|
handle/7,
|
||||||
process_iq/5,
|
process_iq/6,
|
||||||
queue_init/2]).
|
queue_init/3]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
|
|
||||||
start() ->
|
start() ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
add_iq_handler(Component, NS, Module, Function, Type) ->
|
add_iq_handler(Component, Host, NS, Module, Function, Type) ->
|
||||||
case Type of
|
case Type of
|
||||||
no_queue ->
|
no_queue ->
|
||||||
Component:register_iq_handler(NS, Module, Function, no_queue);
|
Component:register_iq_handler(Host, NS, Module, Function, no_queue);
|
||||||
one_queue ->
|
one_queue ->
|
||||||
{ok, Pid} = supervisor:start_child(ejabberd_iq_sup,
|
{ok, Pid} = supervisor:start_child(ejabberd_iq_sup,
|
||||||
[Module, Function]),
|
[Host, Module, Function]),
|
||||||
Component:register_iq_handler(NS, Module, Function,
|
Component:register_iq_handler(Host, NS, Module, Function,
|
||||||
{one_queue, Pid});
|
{one_queue, Pid});
|
||||||
parallel ->
|
parallel ->
|
||||||
Component:register_iq_handler(NS, Module, Function, parallel)
|
Component:register_iq_handler(Host, NS, Module, Function, parallel)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
remove_iq_handler(Component, NS) ->
|
remove_iq_handler(Component, Host, NS) ->
|
||||||
Component:unregister_iq_handler(NS).
|
Component:unregister_iq_handler(NS).
|
||||||
|
|
||||||
stop_iq_handler(Module, Function, Opts) ->
|
stop_iq_handler(Module, Function, Opts) ->
|
||||||
@ -48,20 +48,20 @@ stop_iq_handler(Module, Function, Opts) ->
|
|||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
handle(Module, Function, Opts, From, To, IQ) ->
|
handle(Host, Module, Function, Opts, From, To, IQ) ->
|
||||||
case Opts of
|
case Opts of
|
||||||
no_queue ->
|
no_queue ->
|
||||||
process_iq(Module, Function, From, To, IQ);
|
process_iq(Host, Module, Function, From, To, IQ);
|
||||||
{one_queue, Pid} ->
|
{one_queue, Pid} ->
|
||||||
Pid ! {process_iq, From, To, IQ};
|
Pid ! {process_iq, From, To, IQ};
|
||||||
parallel ->
|
parallel ->
|
||||||
spawn(?MODULE, process_iq, [Module, Function, From, To, IQ]);
|
spawn(?MODULE, process_iq, [Host, Module, Function, From, To, IQ]);
|
||||||
_ ->
|
_ ->
|
||||||
todo
|
todo
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
process_iq(Module, Function, From, To, IQ) ->
|
process_iq(_Host, Module, Function, From, To, IQ) ->
|
||||||
case catch Module:Function(From, To, IQ) of
|
case catch Module:Function(From, To, IQ) of
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
?ERROR_MSG("~p", [Reason]);
|
?ERROR_MSG("~p", [Reason]);
|
||||||
@ -75,18 +75,18 @@ process_iq(Module, Function, From, To, IQ) ->
|
|||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
start_link(Module, Function) ->
|
start_link(Host, Module, Function) ->
|
||||||
{ok, proc_lib:spawn_link(?MODULE, queue_init, [Module, Function])}.
|
{ok, proc_lib:spawn_link(?MODULE, queue_init, [Host, Module, Function])}.
|
||||||
|
|
||||||
queue_init(Module, Function) ->
|
queue_init(Host, Module, Function) ->
|
||||||
queue_loop(Module, Function).
|
queue_loop(Host, Module, Function).
|
||||||
|
|
||||||
% TODO: use gen_event
|
% TODO: use gen_event
|
||||||
queue_loop(Module, Function) ->
|
queue_loop(Host, Module, Function) ->
|
||||||
receive
|
receive
|
||||||
{process_iq, From, To, IQ} ->
|
{process_iq, From, To, IQ} ->
|
||||||
process_iq(Module, Function, From, To, IQ),
|
process_iq(Host, Module, Function, From, To, IQ),
|
||||||
queue_loop(Module, Function);
|
queue_loop(Host, Module, Function);
|
||||||
_ ->
|
_ ->
|
||||||
queue_loop(Module, Function)
|
queue_loop(Host, Module, Function)
|
||||||
end.
|
end.
|
||||||
|
@ -11,58 +11,60 @@
|
|||||||
-vsn('$Revision$ ').
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
-export([start/0,
|
-export([start/0,
|
||||||
start_module/2,
|
start_module/3,
|
||||||
stop_module/1,
|
stop_module/2,
|
||||||
get_opt/2,
|
get_opt/2,
|
||||||
get_opt/3,
|
get_opt/3,
|
||||||
get_module_opt/3,
|
get_module_opt/4,
|
||||||
loaded_modules/0,
|
loaded_modules/1,
|
||||||
loaded_modules_with_opts/0,
|
loaded_modules_with_opts/1,
|
||||||
get_hosts/2]).
|
get_hosts/2,
|
||||||
|
get_module_proc/2]).
|
||||||
|
|
||||||
-export([behaviour_info/1]).
|
-export([behaviour_info/1]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
|
|
||||||
-record(ejabberd_module, {module, opts}).
|
-record(ejabberd_module, {module_host, opts}).
|
||||||
|
|
||||||
behaviour_info(callbacks) ->
|
behaviour_info(callbacks) ->
|
||||||
[{start, 1},
|
[{start, 2},
|
||||||
{stop, 0}];
|
{stop, 1}];
|
||||||
behaviour_info(_Other) ->
|
behaviour_info(_Other) ->
|
||||||
undefined.
|
undefined.
|
||||||
|
|
||||||
start() ->
|
start() ->
|
||||||
ets:new(ejabberd_modules, [named_table,
|
ets:new(ejabberd_modules, [named_table,
|
||||||
public,
|
public,
|
||||||
{keypos, #ejabberd_module.module}]),
|
{keypos, #ejabberd_module.module_host}]),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
|
||||||
start_module(Module, Opts) ->
|
start_module(Host, Module, Opts) ->
|
||||||
case catch Module:start(Opts) of
|
case catch Module:start(Host, Opts) of
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
?ERROR_MSG("~p", [Reason]);
|
?ERROR_MSG("~p", [Reason]);
|
||||||
_ ->
|
_ ->
|
||||||
ets:insert(ejabberd_modules, #ejabberd_module{module = Module,
|
ets:insert(ejabberd_modules,
|
||||||
|
#ejabberd_module{module_host = {Module, Host},
|
||||||
opts = Opts}),
|
opts = Opts}),
|
||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
stop_module(Module) ->
|
stop_module(Host, Module) ->
|
||||||
case catch Module:stop() of
|
case catch Module:stop(Host) of
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
?ERROR_MSG("~p", [Reason]);
|
?ERROR_MSG("~p", [Reason]);
|
||||||
{wait, ProcList} when is_list(ProcList) ->
|
{wait, ProcList} when is_list(ProcList) ->
|
||||||
lists:foreach(fun wait_for_process/1, ProcList),
|
lists:foreach(fun wait_for_process/1, ProcList),
|
||||||
ets:delete(ejabberd_modules, Module),
|
ets:delete(ejabberd_modules, {Module, Host}),
|
||||||
ok;
|
ok;
|
||||||
{wait, Process} ->
|
{wait, Process} ->
|
||||||
wait_for_process(Process),
|
wait_for_process(Process),
|
||||||
ets:delete(ejabberd_modules, Module),
|
ets:delete(ejabberd_modules, {Module, Host}),
|
||||||
ok;
|
ok;
|
||||||
_ ->
|
_ ->
|
||||||
ets:delete(ejabberd_modules, Module),
|
ets:delete(ejabberd_modules, {Module, Host}),
|
||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@ -104,8 +106,8 @@ get_opt(Opt, Opts, Default) ->
|
|||||||
Val
|
Val
|
||||||
end.
|
end.
|
||||||
|
|
||||||
get_module_opt(Module, Opt, Default) ->
|
get_module_opt(Host, Module, Opt, Default) ->
|
||||||
OptsList = ets:lookup(ejabberd_modules, Module),
|
OptsList = ets:lookup(ejabberd_modules, {Module, Host}),
|
||||||
case OptsList of
|
case OptsList of
|
||||||
[] ->
|
[] ->
|
||||||
Default;
|
Default;
|
||||||
@ -113,15 +115,16 @@ get_module_opt(Module, Opt, Default) ->
|
|||||||
get_opt(Opt, Opts, Default)
|
get_opt(Opt, Opts, Default)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
loaded_modules() ->
|
loaded_modules(Host) ->
|
||||||
ets:select(ejabberd_modules,
|
ets:select(ejabberd_modules,
|
||||||
[{#ejabberd_module{_ = '_', module = '$1'},
|
[{#ejabberd_module{_ = '_', module_host = {'$1', Host}},
|
||||||
[],
|
[],
|
||||||
['$1']}]).
|
['$1']}]).
|
||||||
|
|
||||||
loaded_modules_with_opts() ->
|
loaded_modules_with_opts(Host) ->
|
||||||
ets:select(ejabberd_modules,
|
ets:select(ejabberd_modules,
|
||||||
[{#ejabberd_module{_ = '_', module = '$1', opts = '$2'},
|
[{#ejabberd_module{_ = '_', module_host = {'$1', Host},
|
||||||
|
opts = '$2'},
|
||||||
[],
|
[],
|
||||||
[{{'$1', '$2'}}]}]).
|
[{{'$1', '$2'}}]}]).
|
||||||
|
|
||||||
@ -137,3 +140,7 @@ get_hosts(Opts, Prefix) ->
|
|||||||
Hosts ->
|
Hosts ->
|
||||||
Hosts
|
Hosts
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
get_module_proc(Host, Base) ->
|
||||||
|
list_to_atom(atom_to_list(Base) ++ "_" ++ Host).
|
||||||
|
|
||||||
|
@ -11,9 +11,9 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1,
|
-export([start/2,
|
||||||
init/0,
|
init/0,
|
||||||
stop/0,
|
stop/1,
|
||||||
announce/3,
|
announce/3,
|
||||||
send_motd/1]).
|
send_motd/1]).
|
||||||
|
|
||||||
@ -25,17 +25,18 @@
|
|||||||
|
|
||||||
-define(PROCNAME, ejabberd_announce).
|
-define(PROCNAME, ejabberd_announce).
|
||||||
|
|
||||||
start(_) ->
|
start(Host, _Opts) ->
|
||||||
mnesia:create_table(motd, [{disc_copies, [node()]},
|
mnesia:create_table(motd, [{disc_copies, [node()]},
|
||||||
{attributes, record_info(fields, motd)}]),
|
{attributes, record_info(fields, motd)}]),
|
||||||
mnesia:create_table(motd_users, [{disc_copies, [node()]},
|
mnesia:create_table(motd_users, [{disc_copies, [node()]},
|
||||||
{attributes, record_info(fields, motd_users)}]),
|
{attributes, record_info(fields, motd_users)}]),
|
||||||
update_tables(),
|
update_tables(),
|
||||||
ejabberd_hooks:add(local_send_to_resource_hook,
|
ejabberd_hooks:add(local_send_to_resource_hook, Host,
|
||||||
?MODULE, announce, 50),
|
?MODULE, announce, 50),
|
||||||
ejabberd_hooks:add(user_available_hook,
|
ejabberd_hooks:add(user_available_hook, Host,
|
||||||
?MODULE, send_motd, 50),
|
?MODULE, send_motd, 50),
|
||||||
register(?PROCNAME, proc_lib:spawn(?MODULE, init, [])).
|
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
|
proc_lib:spawn(?MODULE, init, [])).
|
||||||
|
|
||||||
init() ->
|
init() ->
|
||||||
loop().
|
loop().
|
||||||
@ -64,36 +65,38 @@ loop() ->
|
|||||||
loop()
|
loop()
|
||||||
end.
|
end.
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
ejabberd_hooks:delete(local_send_to_resource_hook,
|
ejabberd_hooks:delete(local_send_to_resource_hook, Host,
|
||||||
?MODULE, announce, 50),
|
?MODULE, announce, 50),
|
||||||
ejabberd_hooks:delete(sm_register_connection_hook,
|
ejabberd_hooks:delete(sm_register_connection_hook, Host,
|
||||||
?MODULE, send_motd, 50),
|
?MODULE, send_motd, 50),
|
||||||
exit(whereis(?PROCNAME), stop),
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
{wait, ?PROCNAME}.
|
exit(whereis(Proc), stop),
|
||||||
|
{wait, Proc}.
|
||||||
|
|
||||||
announce(From, To, Packet) ->
|
announce(From, To, Packet) ->
|
||||||
case To of
|
case To of
|
||||||
#jid{luser = "", lresource = Res} ->
|
#jid{luser = "", lresource = Res} ->
|
||||||
{xmlelement, Name, _Attrs, _Els} = Packet,
|
{xmlelement, Name, _Attrs, _Els} = Packet,
|
||||||
|
Proc = gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME),
|
||||||
case {Res, Name} of
|
case {Res, Name} of
|
||||||
{"announce/all", "message"} ->
|
{"announce/all", "message"} ->
|
||||||
?PROCNAME ! {announce_all, From, To, Packet},
|
Proc ! {announce_all, From, To, Packet},
|
||||||
stop;
|
stop;
|
||||||
{"announce/online", "message"} ->
|
{"announce/online", "message"} ->
|
||||||
?PROCNAME ! {announce_online, From, To, Packet},
|
Proc ! {announce_online, From, To, Packet},
|
||||||
stop;
|
stop;
|
||||||
{"announce/all-hosts/online", "message"} ->
|
{"announce/all-hosts/online", "message"} ->
|
||||||
?PROCNAME ! {announce_all_hosts_online, From, To, Packet},
|
Proc ! {announce_all_hosts_online, From, To, Packet},
|
||||||
stop;
|
stop;
|
||||||
{"announce/motd", "message"} ->
|
{"announce/motd", "message"} ->
|
||||||
?PROCNAME ! {announce_motd, From, To, Packet},
|
Proc ! {announce_motd, From, To, Packet},
|
||||||
stop;
|
stop;
|
||||||
{"announce/motd/update", "message"} ->
|
{"announce/motd/update", "message"} ->
|
||||||
?PROCNAME ! {announce_motd_update, From, To, Packet},
|
Proc ! {announce_motd_update, From, To, Packet},
|
||||||
stop;
|
stop;
|
||||||
{"announce/motd/delete", "message"} ->
|
{"announce/motd/delete", "message"} ->
|
||||||
?PROCNAME ! {announce_motd_delete, From, To, Packet},
|
Proc ! {announce_motd_delete, From, To, Packet},
|
||||||
stop;
|
stop;
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
@ -103,8 +106,9 @@ announce(From, To, Packet) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
announce_all(From, To, Packet) ->
|
announce_all(From, To, Packet) ->
|
||||||
Access = gen_mod:get_module_opt(?MODULE, access, none),
|
Host = To#jid.lserver,
|
||||||
case acl:match_rule(Access, From) of
|
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
|
||||||
|
case acl:match_rule(Host, Access, From) of
|
||||||
deny ->
|
deny ->
|
||||||
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
||||||
ejabberd_router:route(To, From, Err);
|
ejabberd_router:route(To, From, Err);
|
||||||
@ -114,24 +118,25 @@ announce_all(From, To, Packet) ->
|
|||||||
fun({User, Server}) ->
|
fun({User, Server}) ->
|
||||||
Dest = jlib:make_jid(User, Server, ""),
|
Dest = jlib:make_jid(User, Server, ""),
|
||||||
ejabberd_router:route(Local, Dest, Packet)
|
ejabberd_router:route(Local, Dest, Packet)
|
||||||
end, ejabberd_auth:get_vh_registered_users(To#jid.lserver))
|
end, ejabberd_auth:get_vh_registered_users(Host))
|
||||||
end.
|
end.
|
||||||
|
|
||||||
announce_online(From, To, Packet) ->
|
announce_online(From, To, Packet) ->
|
||||||
Access = gen_mod:get_module_opt(?MODULE, access, none),
|
Host = To#jid.lserver,
|
||||||
case acl:match_rule(Access, From) of
|
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
|
||||||
|
case acl:match_rule(Host, Access, From) of
|
||||||
deny ->
|
deny ->
|
||||||
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
||||||
ejabberd_router:route(To, From, Err);
|
ejabberd_router:route(To, From, Err);
|
||||||
allow ->
|
allow ->
|
||||||
announce_online1(ejabberd_sm:get_vh_session_list(To#jid.lserver),
|
announce_online1(ejabberd_sm:get_vh_session_list(Host),
|
||||||
To#jid.server,
|
To#jid.server,
|
||||||
Packet)
|
Packet)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
announce_all_hosts_online(From, To, Packet) ->
|
announce_all_hosts_online(From, To, Packet) ->
|
||||||
Access = gen_mod:get_module_opt(?MODULE, access, none),
|
Access = gen_mod:get_module_opt(global, ?MODULE, access, none),
|
||||||
case acl:match_rule(Access, From) of
|
case acl:match_rule(global, Access, From) of
|
||||||
deny ->
|
deny ->
|
||||||
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
||||||
ejabberd_router:route(To, From, Err);
|
ejabberd_router:route(To, From, Err);
|
||||||
@ -150,14 +155,15 @@ announce_online1(Sessions, Server, Packet) ->
|
|||||||
end, Sessions).
|
end, Sessions).
|
||||||
|
|
||||||
announce_motd(From, To, Packet) ->
|
announce_motd(From, To, Packet) ->
|
||||||
Access = gen_mod:get_module_opt(?MODULE, access, none),
|
Host = To#jid.lserver,
|
||||||
case acl:match_rule(Access, From) of
|
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
|
||||||
|
case acl:match_rule(Host, Access, From) of
|
||||||
deny ->
|
deny ->
|
||||||
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
||||||
ejabberd_router:route(To, From, Err);
|
ejabberd_router:route(To, From, Err);
|
||||||
allow ->
|
allow ->
|
||||||
announce_motd_update(To#jid.lserver, Packet),
|
announce_motd_update(To#jid.lserver, Packet),
|
||||||
Sessions = ejabberd_sm:get_vh_session_list(To#jid.lserver),
|
Sessions = ejabberd_sm:get_vh_session_list(Host),
|
||||||
announce_online1(Sessions, To#jid.server, Packet),
|
announce_online1(Sessions, To#jid.server, Packet),
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
@ -169,13 +175,14 @@ announce_motd(From, To, Packet) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
announce_motd_update(From, To, Packet) ->
|
announce_motd_update(From, To, Packet) ->
|
||||||
Access = gen_mod:get_module_opt(?MODULE, access, none),
|
Host = To#jid.lserver,
|
||||||
case acl:match_rule(Access, From) of
|
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
|
||||||
|
case acl:match_rule(Host, Access, From) of
|
||||||
deny ->
|
deny ->
|
||||||
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
||||||
ejabberd_router:route(To, From, Err);
|
ejabberd_router:route(To, From, Err);
|
||||||
allow ->
|
allow ->
|
||||||
announce_motd_update(To#jid.lserver, Packet)
|
announce_motd_update(Host, Packet)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
announce_motd_update(LServer, Packet) ->
|
announce_motd_update(LServer, Packet) ->
|
||||||
@ -186,13 +193,14 @@ announce_motd_update(LServer, Packet) ->
|
|||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
announce_motd_delete(From, To, Packet) ->
|
announce_motd_delete(From, To, Packet) ->
|
||||||
Access = gen_mod:get_module_opt(?MODULE, access, none),
|
Host = To#jid.lserver,
|
||||||
case acl:match_rule(Access, From) of
|
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
|
||||||
|
case acl:match_rule(Host, Access, From) of
|
||||||
deny ->
|
deny ->
|
||||||
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
||||||
ejabberd_router:route(To, From, Err);
|
ejabberd_router:route(To, From, Err);
|
||||||
allow ->
|
allow ->
|
||||||
announce_motd_delete(To#jid.lserver)
|
announce_motd_delete(Host)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
announce_motd_delete(LServer) ->
|
announce_motd_delete(LServer) ->
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1,
|
-export([start/2,
|
||||||
stop/0,
|
stop/1,
|
||||||
process_local_iq/3,
|
process_local_iq/3,
|
||||||
process_sm_iq/3]).
|
process_sm_iq/3]).
|
||||||
|
|
||||||
@ -21,22 +21,22 @@
|
|||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
|
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_EJABBERD_CONFIG,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_EJABBERD_CONFIG,
|
||||||
?MODULE, process_local_iq, IQDisc),
|
?MODULE, process_local_iq, IQDisc),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_EJABBERD_CONFIG,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_EJABBERD_CONFIG,
|
||||||
?MODULE, process_sm_iq, IQDisc),
|
?MODULE, process_sm_iq, IQDisc),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_EJABBERD_CONFIG),
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_EJABBERD_CONFIG),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_EJABBERD_CONFIG).
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_EJABBERD_CONFIG).
|
||||||
|
|
||||||
|
|
||||||
process_local_iq(From, _To, #iq{id = ID, type = Type, xmlns = XMLNS,
|
process_local_iq(From, To, #iq{id = ID, type = Type, xmlns = XMLNS,
|
||||||
lang = Lang, sub_el = SubEl} = IQ) ->
|
lang = Lang, sub_el = SubEl} = IQ) ->
|
||||||
case acl:match_rule(configure, From) of
|
case acl:match_rule(To#jid.lserver, configure, From) of
|
||||||
deny ->
|
deny ->
|
||||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||||
allow ->
|
allow ->
|
||||||
@ -719,7 +719,7 @@ search_running_node(SNode, [Node | Nodes]) ->
|
|||||||
|
|
||||||
process_sm_iq(From, To,
|
process_sm_iq(From, To,
|
||||||
#iq{type = Type, xmlns = XMLNS, lang = Lang, sub_el = SubEl} = IQ) ->
|
#iq{type = Type, xmlns = XMLNS, lang = Lang, sub_el = SubEl} = IQ) ->
|
||||||
case acl:match_rule(configure, From) of
|
case acl:match_rule(To#jid.lserver, configure, From) of
|
||||||
deny ->
|
deny ->
|
||||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||||
allow ->
|
allow ->
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1,
|
-export([start/2,
|
||||||
stop/0,
|
stop/1,
|
||||||
process_local_iq/3]).
|
process_local_iq/3]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
@ -21,18 +21,18 @@
|
|||||||
|
|
||||||
-define(NS_ECONFIGURE, "http://ejabberd.jabberstudio.org/protocol/configure").
|
-define(NS_ECONFIGURE, "http://ejabberd.jabberstudio.org/protocol/configure").
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_ECONFIGURE,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_ECONFIGURE,
|
||||||
?MODULE, process_local_iq, IQDisc),
|
?MODULE, process_local_iq, IQDisc),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_ECONFIGURE).
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_ECONFIGURE).
|
||||||
|
|
||||||
|
|
||||||
process_local_iq(From, _To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
process_local_iq(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
||||||
case acl:match_rule(configure, From) of
|
case acl:match_rule(To#jid.lserver, configure, From) of
|
||||||
deny ->
|
deny ->
|
||||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||||
allow ->
|
allow ->
|
||||||
|
@ -12,18 +12,18 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1,
|
-export([start/2,
|
||||||
stop/0,
|
stop/1,
|
||||||
process_local_iq_items/3,
|
process_local_iq_items/3,
|
||||||
process_local_iq_info/3,
|
process_local_iq_info/3,
|
||||||
process_sm_iq_items/3,
|
process_sm_iq_items/3,
|
||||||
process_sm_iq_info/3,
|
process_sm_iq_info/3,
|
||||||
register_feature/1,
|
register_feature/2,
|
||||||
unregister_feature/1,
|
unregister_feature/2,
|
||||||
register_extra_domain/1,
|
register_extra_domain/1,
|
||||||
unregister_extra_domain/1,
|
unregister_extra_domain/1,
|
||||||
register_sm_feature/1,
|
register_sm_feature/2,
|
||||||
unregister_sm_feature/1,
|
unregister_sm_feature/2,
|
||||||
register_sm_node/4,
|
register_sm_node/4,
|
||||||
unregister_sm_node/1]).
|
unregister_sm_node/1]).
|
||||||
|
|
||||||
@ -36,23 +36,23 @@
|
|||||||
[{"xmlns", ?NS_DISCO_INFO},
|
[{"xmlns", ?NS_DISCO_INFO},
|
||||||
{"node", SNode}], []}]}).
|
{"node", SNode}], []}]}).
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
ejabberd_local:refresh_iq_handlers(),
|
ejabberd_local:refresh_iq_handlers(),
|
||||||
|
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_DISCO_ITEMS,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS,
|
||||||
?MODULE, process_local_iq_items, IQDisc),
|
?MODULE, process_local_iq_items, IQDisc),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_DISCO_INFO,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO,
|
||||||
?MODULE, process_local_iq_info, IQDisc),
|
?MODULE, process_local_iq_info, IQDisc),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_DISCO_ITEMS,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS,
|
||||||
?MODULE, process_sm_iq_items, IQDisc),
|
?MODULE, process_sm_iq_items, IQDisc),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_DISCO_INFO,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_DISCO_INFO,
|
||||||
?MODULE, process_sm_iq_info, IQDisc),
|
?MODULE, process_sm_iq_info, IQDisc),
|
||||||
|
|
||||||
catch ets:new(disco_features, [named_table, ordered_set, public]),
|
catch ets:new(disco_features, [named_table, ordered_set, public]),
|
||||||
register_feature("iq"),
|
register_feature(Host, "iq"),
|
||||||
register_feature("presence"),
|
register_feature(Host, "presence"),
|
||||||
register_feature("presence-invisible"),
|
register_feature(Host, "presence-invisible"),
|
||||||
|
|
||||||
catch ets:new(disco_extra_domains, [named_table, ordered_set, public]),
|
catch ets:new(disco_extra_domains, [named_table, ordered_set, public]),
|
||||||
ExtraDomains = gen_mod:get_opt(extra_domains, Opts, []),
|
ExtraDomains = gen_mod:get_opt(extra_domains, Opts, []),
|
||||||
@ -61,23 +61,23 @@ start(Opts) ->
|
|||||||
catch ets:new(disco_sm_nodes, [named_table, ordered_set, public]),
|
catch ets:new(disco_sm_nodes, [named_table, ordered_set, public]),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_DISCO_ITEMS),
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_DISCO_INFO),
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_DISCO_ITEMS),
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_DISCO_INFO),
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_INFO),
|
||||||
catch ets:delete(disco_features),
|
catch ets:delete(disco_features),
|
||||||
catch ets:delete(disco_extra_domains),
|
catch ets:delete(disco_extra_domains),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
|
||||||
register_feature(Feature) ->
|
register_feature(Host, Feature) ->
|
||||||
catch ets:new(disco_features, [named_table, ordered_set, public]),
|
catch ets:new(disco_features, [named_table, ordered_set, public]),
|
||||||
ets:insert(disco_features, {Feature}).
|
ets:insert(disco_features, {{Feature, Host}}).
|
||||||
|
|
||||||
unregister_feature(Feature) ->
|
unregister_feature(Host, Feature) ->
|
||||||
catch ets:new(disco_features, [named_table, ordered_set, public]),
|
catch ets:new(disco_features, [named_table, ordered_set, public]),
|
||||||
ets:delete(disco_features, Feature).
|
ets:delete(disco_features, {Feature, Host}).
|
||||||
|
|
||||||
register_extra_domain(Domain) ->
|
register_extra_domain(Domain) ->
|
||||||
catch ets:new(disco_extra_domains, [named_table, ordered_set, public]),
|
catch ets:new(disco_extra_domains, [named_table, ordered_set, public]),
|
||||||
@ -94,18 +94,19 @@ process_local_iq_items(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} =
|
|||||||
get ->
|
get ->
|
||||||
SNode = xml:get_tag_attr_s("node", SubEl),
|
SNode = xml:get_tag_attr_s("node", SubEl),
|
||||||
Node = string:tokens(SNode, "/"),
|
Node = string:tokens(SNode, "/"),
|
||||||
|
Host = To#jid.lserver,
|
||||||
|
|
||||||
case acl:match_rule(configure, From) of
|
case acl:match_rule(Host, configure, From) of
|
||||||
deny when Node /= [] ->
|
deny when Node /= [] ->
|
||||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||||
deny ->
|
deny ->
|
||||||
IQ#iq{type = result,
|
IQ#iq{type = result,
|
||||||
sub_el = [{xmlelement, "query",
|
sub_el = [{xmlelement, "query",
|
||||||
[{"xmlns", ?NS_DISCO_ITEMS}],
|
[{"xmlns", ?NS_DISCO_ITEMS}],
|
||||||
get_services_only(To#jid.lserver)
|
get_services_only(Host)
|
||||||
}]};
|
}]};
|
||||||
_ ->
|
_ ->
|
||||||
case get_local_items(To#jid.lserver, Node,
|
case get_local_items(Host, Node,
|
||||||
jlib:jid_to_string(To), Lang) of
|
jlib:jid_to_string(To), Lang) of
|
||||||
{result, Res} ->
|
{result, Res} ->
|
||||||
IQ#iq{type = result,
|
IQ#iq{type = result,
|
||||||
@ -121,7 +122,7 @@ process_local_iq_items(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} =
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
process_local_iq_info(From, _To, #iq{type = Type, xmlns = XMLNS,
|
process_local_iq_info(From, To, #iq{type = Type, xmlns = XMLNS,
|
||||||
sub_el = SubEl} = IQ) ->
|
sub_el = SubEl} = IQ) ->
|
||||||
case Type of
|
case Type of
|
||||||
set ->
|
set ->
|
||||||
@ -129,7 +130,7 @@ process_local_iq_info(From, _To, #iq{type = Type, xmlns = XMLNS,
|
|||||||
get ->
|
get ->
|
||||||
SNode = xml:get_tag_attr_s("node", SubEl),
|
SNode = xml:get_tag_attr_s("node", SubEl),
|
||||||
Node = string:tokens(SNode, "/"),
|
Node = string:tokens(SNode, "/"),
|
||||||
case {acl:match_rule(configure, From), Node} of
|
case {acl:match_rule(To#jid.lserver, configure, From), Node} of
|
||||||
{_, []} ->
|
{_, []} ->
|
||||||
Features = lists:map(fun feature_to_xml/1,
|
Features = lists:map(fun feature_to_xml/1,
|
||||||
ets:tab2list(disco_features)),
|
ets:tab2list(disco_features)),
|
||||||
@ -162,7 +163,7 @@ process_local_iq_info(From, _To, #iq{type = Type, xmlns = XMLNS,
|
|||||||
[{"category", "ejabberd"},
|
[{"category", "ejabberd"},
|
||||||
{"type", "node"},
|
{"type", "node"},
|
||||||
{"name", ENode}], []},
|
{"name", ENode}], []},
|
||||||
feature_to_xml({?NS_STATS})
|
feature_to_xml(?NS_STATS)
|
||||||
]
|
]
|
||||||
}]};
|
}]};
|
||||||
{allow, ["running nodes", ENode, "DB"]} ->
|
{allow, ["running nodes", ENode, "DB"]} ->
|
||||||
@ -171,7 +172,7 @@ process_local_iq_info(From, _To, #iq{type = Type, xmlns = XMLNS,
|
|||||||
"query",
|
"query",
|
||||||
[{"xmlns", XMLNS},
|
[{"xmlns", XMLNS},
|
||||||
{"node", SNode}],
|
{"node", SNode}],
|
||||||
[feature_to_xml({?NS_EJABBERD_CONFIG})]}]};
|
[feature_to_xml(?NS_EJABBERD_CONFIG)]}]};
|
||||||
{allow, ["running nodes", ENode, "modules"]} ->
|
{allow, ["running nodes", ENode, "modules"]} ->
|
||||||
?EMPTY_INFO_RESULT;
|
?EMPTY_INFO_RESULT;
|
||||||
{allow, ["running nodes", ENode, "modules", _]} ->
|
{allow, ["running nodes", ENode, "modules", _]} ->
|
||||||
@ -179,7 +180,7 @@ process_local_iq_info(From, _To, #iq{type = Type, xmlns = XMLNS,
|
|||||||
sub_el = [{xmlelement, "query",
|
sub_el = [{xmlelement, "query",
|
||||||
[{"xmlns", XMLNS},
|
[{"xmlns", XMLNS},
|
||||||
{"node", SNode}],
|
{"node", SNode}],
|
||||||
[feature_to_xml({?NS_EJABBERD_CONFIG})]}]};
|
[feature_to_xml(?NS_EJABBERD_CONFIG)]}]};
|
||||||
{allow, ["running nodes", ENode, "backup"]} ->
|
{allow, ["running nodes", ENode, "backup"]} ->
|
||||||
?EMPTY_INFO_RESULT;
|
?EMPTY_INFO_RESULT;
|
||||||
{allow, ["running nodes", ENode, "backup", _]} ->
|
{allow, ["running nodes", ENode, "backup", _]} ->
|
||||||
@ -187,7 +188,7 @@ process_local_iq_info(From, _To, #iq{type = Type, xmlns = XMLNS,
|
|||||||
sub_el = [{xmlelement, "query",
|
sub_el = [{xmlelement, "query",
|
||||||
[{"xmlns", XMLNS},
|
[{"xmlns", XMLNS},
|
||||||
{"node", SNode}],
|
{"node", SNode}],
|
||||||
[feature_to_xml({?NS_EJABBERD_CONFIG})]}]};
|
[feature_to_xml(?NS_EJABBERD_CONFIG)]}]};
|
||||||
{allow, ["running nodes", ENode, "import"]} ->
|
{allow, ["running nodes", ENode, "import"]} ->
|
||||||
?EMPTY_INFO_RESULT;
|
?EMPTY_INFO_RESULT;
|
||||||
{allow, ["running nodes", ENode, "import", _]} ->
|
{allow, ["running nodes", ENode, "import", _]} ->
|
||||||
@ -195,20 +196,22 @@ process_local_iq_info(From, _To, #iq{type = Type, xmlns = XMLNS,
|
|||||||
sub_el = [{xmlelement, "query",
|
sub_el = [{xmlelement, "query",
|
||||||
[{"xmlns", XMLNS},
|
[{"xmlns", XMLNS},
|
||||||
{"node", SNode}],
|
{"node", SNode}],
|
||||||
[feature_to_xml({?NS_EJABBERD_CONFIG})]}]};
|
[feature_to_xml(?NS_EJABBERD_CONFIG)]}]};
|
||||||
{allow, ["config", _]} ->
|
{allow, ["config", _]} ->
|
||||||
IQ#iq{type = result,
|
IQ#iq{type = result,
|
||||||
sub_el = [{xmlelement, "query",
|
sub_el = [{xmlelement, "query",
|
||||||
[{"xmlns", XMLNS},
|
[{"xmlns", XMLNS},
|
||||||
{"node", SNode}],
|
{"node", SNode}],
|
||||||
[feature_to_xml({?NS_EJABBERD_CONFIG})]}]};
|
[feature_to_xml(?NS_EJABBERD_CONFIG)]}]};
|
||||||
_ ->
|
_ ->
|
||||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}
|
IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
feature_to_xml({Feature}) ->
|
feature_to_xml({{Feature, _Host}}) ->
|
||||||
|
feature_to_xml(Feature);
|
||||||
|
feature_to_xml(Feature) when is_list(Feature) ->
|
||||||
{xmlelement, "feature", [{"var", Feature}], []}.
|
{xmlelement, "feature", [{"var", Feature}], []}.
|
||||||
|
|
||||||
domain_to_xml({Domain}) ->
|
domain_to_xml({Domain}) ->
|
||||||
@ -488,13 +491,13 @@ get_stopped_nodes(Lang) ->
|
|||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
register_sm_feature(Feature) ->
|
register_sm_feature(Host, Feature) ->
|
||||||
catch ets:new(disco_sm_features, [named_table, ordered_set, public]),
|
catch ets:new(disco_sm_features, [named_table, ordered_set, public]),
|
||||||
ets:insert(disco_sm_features, {Feature}).
|
ets:insert(disco_sm_features, {{Feature, Host}}).
|
||||||
|
|
||||||
unregister_sm_feature(Feature) ->
|
unregister_sm_feature(Host, Feature) ->
|
||||||
catch ets:new(disco_sm_features, [named_table, ordered_set, public]),
|
catch ets:new(disco_sm_features, [named_table, ordered_set, public]),
|
||||||
ets:delete(disco_sm_features, Feature).
|
ets:delete(disco_sm_features, {Feature, Host}).
|
||||||
|
|
||||||
register_sm_node(Node, Name, Module, Function) ->
|
register_sm_node(Node, Name, Module, Function) ->
|
||||||
catch ets:new(disco_sm_nodes, [named_table, ordered_set, public]),
|
catch ets:new(disco_sm_nodes, [named_table, ordered_set, public]),
|
||||||
@ -509,7 +512,7 @@ process_sm_iq_items(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ
|
|||||||
#jid{luser = LFrom, lserver = LServer} = From,
|
#jid{luser = LFrom, lserver = LServer} = From,
|
||||||
Self = (LTo == LFrom) andalso (LServer == ?MYNAME),
|
Self = (LTo == LFrom) andalso (LServer == ?MYNAME),
|
||||||
Node = xml:get_tag_attr_s("node", SubEl),
|
Node = xml:get_tag_attr_s("node", SubEl),
|
||||||
case {acl:match_rule(configure, From), Type, Self, Node} of
|
case {acl:match_rule(To#jid.lserver, configure, From), Type, Self, Node} of
|
||||||
{_, set, _, _} ->
|
{_, set, _, _} ->
|
||||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||||
{_, get, true, []} ->
|
{_, get, true, []} ->
|
||||||
@ -561,7 +564,7 @@ process_sm_iq_info(From, To, #iq{type = Type, xmlns = XMLNS,
|
|||||||
#jid{luser = LFrom, lserver = LServer} = From,
|
#jid{luser = LFrom, lserver = LServer} = From,
|
||||||
Self = (LTo == LFrom) andalso (LServer == ?MYNAME),
|
Self = (LTo == LFrom) andalso (LServer == ?MYNAME),
|
||||||
Node = xml:get_tag_attr_s("node", SubEl),
|
Node = xml:get_tag_attr_s("node", SubEl),
|
||||||
case {acl:match_rule(configure, From), Type, Self, Node} of
|
case {acl:match_rule(To#jid.lserver, configure, From), Type, Self, Node} of
|
||||||
{_, set, _, _} ->
|
{_, set, _, _} ->
|
||||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||||
{allow, get, _, []} ->
|
{allow, get, _, []} ->
|
||||||
@ -569,7 +572,7 @@ process_sm_iq_info(From, To, #iq{type = Type, xmlns = XMLNS,
|
|||||||
ets:tab2list(disco_sm_features)),
|
ets:tab2list(disco_sm_features)),
|
||||||
IQ#iq{type = result,
|
IQ#iq{type = result,
|
||||||
sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}],
|
sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}],
|
||||||
[feature_to_xml({?NS_EJABBERD_CONFIG})] ++
|
[feature_to_xml(?NS_EJABBERD_CONFIG)] ++
|
||||||
Features}]};
|
Features}]};
|
||||||
{_, get, _, []} ->
|
{_, get, _, []} ->
|
||||||
Features = lists:map(fun feature_to_xml/1,
|
Features = lists:map(fun feature_to_xml/1,
|
||||||
|
@ -12,17 +12,17 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1, init/1, stop/0]).
|
-export([start/2, init/1, stop/1]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
|
|
||||||
-define(PROCNAME, ejabberd_mod_echo).
|
-define(PROCNAME, ejabberd_mod_echo).
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
%Host = gen_mod:get_opt(host, Opts),
|
MyHost = gen_mod:get_opt(host, Opts, "echo." ++ Host),
|
||||||
Host = gen_mod:get_opt(host, Opts, "echo." ++ ?MYNAME),
|
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
register(?PROCNAME, spawn(?MODULE, init, [Host])).
|
spawn(?MODULE, init, [MyHost])).
|
||||||
|
|
||||||
init(Host) ->
|
init(Host) ->
|
||||||
ejabberd_router:register_route(Host),
|
ejabberd_router:register_route(Host),
|
||||||
@ -40,7 +40,8 @@ loop(Host) ->
|
|||||||
loop(Host)
|
loop(Host)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
?PROCNAME ! stop,
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
{wait, ?PROCNAME}.
|
Proc ! stop,
|
||||||
|
{wait, Proc}.
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1, init/2, stop/0,
|
-export([start/2, init/2, stop/1,
|
||||||
closed_connection/3,
|
closed_connection/3,
|
||||||
get_user_and_encoding/3]).
|
get_user_and_encoding/3]).
|
||||||
|
|
||||||
@ -26,44 +26,44 @@
|
|||||||
|
|
||||||
-define(PROCNAME, ejabberd_mod_irc).
|
-define(PROCNAME, ejabberd_mod_irc).
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
iconv:start(),
|
iconv:start(),
|
||||||
mnesia:create_table(irc_custom,
|
mnesia:create_table(irc_custom,
|
||||||
[{disc_copies, [node()]},
|
[{disc_copies, [node()]},
|
||||||
{attributes, record_info(fields, irc_custom)}]),
|
{attributes, record_info(fields, irc_custom)}]),
|
||||||
Hosts = gen_mod:get_hosts(Opts, "irc."),
|
MyHost = gen_mod:get_opt(host, Opts, "irc." ++ Host),
|
||||||
Host = hd(Hosts),
|
update_table(MyHost),
|
||||||
update_table(Host),
|
|
||||||
Access = gen_mod:get_opt(access, Opts, all),
|
Access = gen_mod:get_opt(access, Opts, all),
|
||||||
register(?PROCNAME, spawn(?MODULE, init, [Hosts, Access])).
|
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
|
spawn(?MODULE, init, [MyHost, Access])).
|
||||||
|
|
||||||
init(Hosts, Access) ->
|
init(Host, Access) ->
|
||||||
catch ets:new(irc_connection, [named_table,
|
catch ets:new(irc_connection, [named_table,
|
||||||
public,
|
public,
|
||||||
{keypos, #irc_connection.jid_server_host}]),
|
{keypos, #irc_connection.jid_server_host}]),
|
||||||
ejabberd_router:register_routes(Hosts),
|
ejabberd_router:register_route(Host),
|
||||||
loop(Hosts, Access).
|
loop(Host, Access).
|
||||||
|
|
||||||
loop(Hosts, Access) ->
|
loop(Host, Access) ->
|
||||||
receive
|
receive
|
||||||
{route, From, To, Packet} ->
|
{route, From, To, Packet} ->
|
||||||
case catch do_route(To#jid.lserver, Access, From, To, Packet) of
|
case catch do_route(Host, Access, From, To, Packet) of
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
?ERROR_MSG("~p", [Reason]);
|
?ERROR_MSG("~p", [Reason]);
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
loop(Hosts, Access);
|
loop(Host, Access);
|
||||||
stop ->
|
stop ->
|
||||||
ejabberd_router:unregister_routes(Hosts),
|
ejabberd_router:unregister_route(Host),
|
||||||
ok;
|
ok;
|
||||||
_ ->
|
_ ->
|
||||||
loop(Hosts, Access)
|
loop(Host, Access)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
do_route(Host, Access, From, To, Packet) ->
|
do_route(Host, Access, From, To, Packet) ->
|
||||||
case acl:match_rule(Access, From) of
|
case acl:match_rule(Host, Access, From) of
|
||||||
allow ->
|
allow ->
|
||||||
do_route1(Host, From, To, Packet);
|
do_route1(Host, From, To, Packet);
|
||||||
_ ->
|
_ ->
|
||||||
@ -174,9 +174,10 @@ do_route1(Host, From, To, Packet) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
?PROCNAME ! stop,
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
{wait, ?PROCNAME}.
|
Proc ! stop,
|
||||||
|
{wait, Proc}.
|
||||||
|
|
||||||
|
|
||||||
closed_connection(Host, From, Server) ->
|
closed_connection(Host, From, Server) ->
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1,
|
-export([start/2,
|
||||||
stop/0,
|
stop/1,
|
||||||
process_local_iq/3,
|
process_local_iq/3,
|
||||||
process_sm_iq/3,
|
process_sm_iq/3,
|
||||||
on_presence_update/4,
|
on_presence_update/4,
|
||||||
@ -26,28 +26,28 @@
|
|||||||
-record(last_activity, {us, timestamp, status}).
|
-record(last_activity, {us, timestamp, status}).
|
||||||
|
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
mnesia:create_table(last_activity,
|
mnesia:create_table(last_activity,
|
||||||
[{disc_copies, [node()]},
|
[{disc_copies, [node()]},
|
||||||
{attributes, record_info(fields, last_activity)}]),
|
{attributes, record_info(fields, last_activity)}]),
|
||||||
update_table(),
|
update_table(),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_LAST,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST,
|
||||||
?MODULE, process_local_iq, IQDisc),
|
?MODULE, process_local_iq, IQDisc),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_LAST,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_LAST,
|
||||||
?MODULE, process_sm_iq, IQDisc),
|
?MODULE, process_sm_iq, IQDisc),
|
||||||
ejabberd_hooks:add(remove_user,
|
ejabberd_hooks:add(remove_user, Host,
|
||||||
?MODULE, remove_user, 50),
|
?MODULE, remove_user, 50),
|
||||||
ejabberd_hooks:add(unset_presence_hook,
|
ejabberd_hooks:add(unset_presence_hook, Host,
|
||||||
?MODULE, on_presence_update, 50).
|
?MODULE, on_presence_update, 50).
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
ejabberd_hooks:delete(remove_user,
|
ejabberd_hooks:delete(remove_user, Host,
|
||||||
?MODULE, remove_user, 50),
|
?MODULE, remove_user, 50),
|
||||||
ejabberd_hooks:delete(unset_presence_hook,
|
ejabberd_hooks:delete(unset_presence_hook, Host,
|
||||||
?MODULE, on_presence_update, 50),
|
?MODULE, on_presence_update, 50),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_LAST),
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_LAST),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_LAST).
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_LAST).
|
||||||
|
|
||||||
process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
||||||
case Type of
|
case Type of
|
||||||
@ -72,7 +72,8 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
|||||||
Server = To#jid.lserver,
|
Server = To#jid.lserver,
|
||||||
{Subscription, _Groups} =
|
{Subscription, _Groups} =
|
||||||
ejabberd_hooks:run_fold(
|
ejabberd_hooks:run_fold(
|
||||||
roster_get_jid_info, {none, []}, [User, Server, From]),
|
roster_get_jid_info, Server,
|
||||||
|
{none, []}, [User, Server, From]),
|
||||||
if
|
if
|
||||||
(Subscription == both) or (Subscription == from) ->
|
(Subscription == both) or (Subscription == from) ->
|
||||||
case catch mod_privacy:get_user_list(User, Server) of
|
case catch mod_privacy:get_user_list(User, Server) of
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1,
|
-export([start/2,
|
||||||
stop/0,
|
stop/1,
|
||||||
process_local_iq/3,
|
process_local_iq/3,
|
||||||
process_sm_iq/3,
|
process_sm_iq/3,
|
||||||
on_presence_update/4,
|
on_presence_update/4,
|
||||||
@ -24,24 +24,24 @@
|
|||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
|
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_LAST,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST,
|
||||||
?MODULE, process_local_iq, IQDisc),
|
?MODULE, process_local_iq, IQDisc),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_LAST,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_LAST,
|
||||||
?MODULE, process_sm_iq, IQDisc),
|
?MODULE, process_sm_iq, IQDisc),
|
||||||
ejabberd_hooks:add(remove_user,
|
ejabberd_hooks:add(remove_user, Host,
|
||||||
?MODULE, remove_user, 50),
|
?MODULE, remove_user, 50),
|
||||||
ejabberd_hooks:add(unset_presence_hook,
|
ejabberd_hooks:add(unset_presence_hook, Host,
|
||||||
?MODULE, on_presence_update, 50).
|
?MODULE, on_presence_update, 50).
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
ejabberd_hooks:delete(remove_user,
|
ejabberd_hooks:delete(remove_user, Host,
|
||||||
?MODULE, remove_user, 50),
|
?MODULE, remove_user, 50),
|
||||||
ejabberd_hooks:delete(unset_presence_hook,
|
ejabberd_hooks:delete(unset_presence_hook, Host,
|
||||||
?MODULE, on_presence_update, 50),
|
?MODULE, on_presence_update, 50),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_LAST),
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_LAST),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_LAST).
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_LAST).
|
||||||
|
|
||||||
process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
||||||
case Type of
|
case Type of
|
||||||
@ -66,7 +66,8 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
|||||||
Server = To#jid.lserver,
|
Server = To#jid.lserver,
|
||||||
{Subscription, _Groups} =
|
{Subscription, _Groups} =
|
||||||
ejabberd_hooks:run_fold(
|
ejabberd_hooks:run_fold(
|
||||||
roster_get_jid_info, {none, []}, [User, From]),
|
roster_get_jid_info, Server,
|
||||||
|
{none, []}, [User, From]),
|
||||||
if
|
if
|
||||||
(Subscription == both) or (Subscription == from) ->
|
(Subscription == both) or (Subscription == from) ->
|
||||||
case catch mod_privacy:get_user_list(User, Server) of
|
case catch mod_privacy:get_user_list(User, Server) of
|
||||||
|
@ -12,10 +12,10 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1,
|
-export([start/2,
|
||||||
init/2,
|
init/3,
|
||||||
stop/0,
|
stop/1,
|
||||||
room_destroyed/2,
|
room_destroyed/3,
|
||||||
store_room/3,
|
store_room/3,
|
||||||
restore_room/2,
|
restore_room/2,
|
||||||
forget_room/2,
|
forget_room/2,
|
||||||
@ -32,60 +32,59 @@
|
|||||||
|
|
||||||
-define(PROCNAME, ejabberd_mod_muc).
|
-define(PROCNAME, ejabberd_mod_muc).
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
mnesia:create_table(muc_room,
|
mnesia:create_table(muc_room,
|
||||||
[{disc_copies, [node()]},
|
[{disc_copies, [node()]},
|
||||||
{attributes, record_info(fields, muc_room)}]),
|
{attributes, record_info(fields, muc_room)}]),
|
||||||
mnesia:create_table(muc_registered,
|
mnesia:create_table(muc_registered,
|
||||||
[{disc_copies, [node()]},
|
[{disc_copies, [node()]},
|
||||||
{attributes, record_info(fields, muc_registered)}]),
|
{attributes, record_info(fields, muc_registered)}]),
|
||||||
Hosts = gen_mod:get_hosts(Opts, "conference."),
|
MyHost = gen_mod:get_opt(host, Opts, "conference." ++ Host),
|
||||||
Host = hd(Hosts),
|
update_tables(MyHost),
|
||||||
update_tables(Host),
|
|
||||||
mnesia:add_table_index(muc_registered, nick),
|
mnesia:add_table_index(muc_registered, nick),
|
||||||
Access = gen_mod:get_opt(access, Opts, all),
|
Access = gen_mod:get_opt(access, Opts, all),
|
||||||
AccessCreate = gen_mod:get_opt(access_create, Opts, all),
|
AccessCreate = gen_mod:get_opt(access_create, Opts, all),
|
||||||
AccessAdmin = gen_mod:get_opt(access_admin, Opts, none),
|
AccessAdmin = gen_mod:get_opt(access_admin, Opts, none),
|
||||||
register(?PROCNAME,
|
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
spawn(?MODULE, init,
|
spawn(?MODULE, init,
|
||||||
[Hosts, {Access, AccessCreate, AccessAdmin}])).
|
[MyHost, Host, {Access, AccessCreate, AccessAdmin}])).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
init(Hosts, Access) ->
|
init(Host, ServerHost, Access) ->
|
||||||
catch ets:new(muc_online_room, [named_table,
|
catch ets:new(muc_online_room, [named_table,
|
||||||
public,
|
public,
|
||||||
{keypos, #muc_online_room.name_host}]),
|
{keypos, #muc_online_room.name_host}]),
|
||||||
ejabberd_router:register_routes(Hosts),
|
ejabberd_router:register_route(Host),
|
||||||
load_permanent_rooms(Access),
|
load_permanent_rooms(Host, ServerHost, Access),
|
||||||
loop(Hosts, Access).
|
loop(Host, ServerHost, Access).
|
||||||
|
|
||||||
loop(Hosts, Access) ->
|
loop(Host, ServerHost, Access) ->
|
||||||
receive
|
receive
|
||||||
{route, From, To, Packet} ->
|
{route, From, To, Packet} ->
|
||||||
case catch do_route(To#jid.lserver, Access, From, To, Packet) of
|
case catch do_route(Host, ServerHost, Access, From, To, Packet) of
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
?ERROR_MSG("~p", [Reason]);
|
?ERROR_MSG("~p", [Reason]);
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
loop(Hosts, Access);
|
loop(Host, ServerHost, Access);
|
||||||
{room_destroyed, RoomHost} ->
|
{room_destroyed, RoomHost} ->
|
||||||
ets:delete(muc_online_room, RoomHost),
|
ets:delete(muc_online_room, RoomHost),
|
||||||
loop(Hosts, Access);
|
loop(Host, ServerHost, Access);
|
||||||
stop ->
|
stop ->
|
||||||
ejabberd_router:unregister_routes(Hosts),
|
ejabberd_router:unregister_route(Host),
|
||||||
ok;
|
ok;
|
||||||
_ ->
|
_ ->
|
||||||
loop(Hosts, Access)
|
loop(Host, ServerHost, Access)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
do_route(Host, Access, From, To, Packet) ->
|
do_route(Host, ServerHost, Access, From, To, Packet) ->
|
||||||
{AccessRoute, _AccessCreate, _AccessAdmin} = Access,
|
{AccessRoute, _AccessCreate, _AccessAdmin} = Access,
|
||||||
case acl:match_rule(AccessRoute, From) of
|
case acl:match_rule(ServerHost, AccessRoute, From) of
|
||||||
allow ->
|
allow ->
|
||||||
do_route1(Host, Access, From, To, Packet);
|
do_route1(Host, ServerHost, Access, From, To, Packet);
|
||||||
_ ->
|
_ ->
|
||||||
{xmlelement, _Name, Attrs, _Els} = Packet,
|
{xmlelement, _Name, Attrs, _Els} = Packet,
|
||||||
Lang = xml:get_attr_s("xml:lang", Attrs),
|
Lang = xml:get_attr_s("xml:lang", Attrs),
|
||||||
@ -96,7 +95,7 @@ do_route(Host, Access, From, To, Packet) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
do_route1(Host, Access, From, To, Packet) ->
|
do_route1(Host, ServerHost, Access, From, To, Packet) ->
|
||||||
{_AccessRoute, AccessCreate, AccessAdmin} = Access,
|
{_AccessRoute, AccessCreate, AccessAdmin} = Access,
|
||||||
{Room, _, Nick} = jlib:jid_tolower(To),
|
{Room, _, Nick} = jlib:jid_tolower(To),
|
||||||
{xmlelement, Name, Attrs, _Els} = Packet,
|
{xmlelement, Name, Attrs, _Els} = Packet,
|
||||||
@ -178,7 +177,7 @@ do_route1(Host, Access, From, To, Packet) ->
|
|||||||
"error" ->
|
"error" ->
|
||||||
ok;
|
ok;
|
||||||
_ ->
|
_ ->
|
||||||
case acl:match_rule(AccessAdmin, From) of
|
case acl:match_rule(ServerHost, AccessAdmin, From) of
|
||||||
allow ->
|
allow ->
|
||||||
Msg = xml:get_path_s(
|
Msg = xml:get_path_s(
|
||||||
Packet,
|
Packet,
|
||||||
@ -216,11 +215,12 @@ do_route1(Host, Access, From, To, Packet) ->
|
|||||||
Type = xml:get_attr_s("type", Attrs),
|
Type = xml:get_attr_s("type", Attrs),
|
||||||
case {Name, Type} of
|
case {Name, Type} of
|
||||||
{"presence", ""} ->
|
{"presence", ""} ->
|
||||||
case acl:match_rule(AccessCreate, From) of
|
case acl:match_rule(ServerHost, AccessCreate, From) of
|
||||||
allow ->
|
allow ->
|
||||||
?DEBUG("MUC: open new room '~s'~n", [Room]),
|
?DEBUG("MUC: open new room '~s'~n", [Room]),
|
||||||
{ok, Pid} = mod_muc_room:start(
|
{ok, Pid} = mod_muc_room:start(
|
||||||
Host, Access, Room, From, Nick),
|
Host, ServerHost, Access,
|
||||||
|
Room, From, Nick),
|
||||||
ets:insert(
|
ets:insert(
|
||||||
muc_online_room,
|
muc_online_room,
|
||||||
#muc_online_room{name_host = {Room, Host},
|
#muc_online_room{name_host = {Room, Host},
|
||||||
@ -252,13 +252,15 @@ do_route1(Host, Access, From, To, Packet) ->
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
room_destroyed(Host, Room) ->
|
room_destroyed(Host, Room, ServerHost) ->
|
||||||
?PROCNAME ! {room_destroyed, {Room, Host}},
|
gen_mod:get_module_proc(ServerHost, ?PROCNAME) !
|
||||||
|
{room_destroyed, {Room, Host}},
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
?PROCNAME ! stop,
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
{wait, ?PROCNAME}.
|
Proc ! stop,
|
||||||
|
{wait, Proc}.
|
||||||
|
|
||||||
|
|
||||||
store_room(Host, Name, Opts) ->
|
store_room(Host, Name, Opts) ->
|
||||||
@ -284,8 +286,11 @@ forget_room(Host, Name) ->
|
|||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
|
|
||||||
load_permanent_rooms(Access) ->
|
load_permanent_rooms(Host, ServerHost, Access) ->
|
||||||
case catch mnesia:dirty_select(muc_room, [{'_', [], ['$_']}]) of
|
case catch mnesia:dirty_select(
|
||||||
|
muc_room, [{#muc_room{name_host = {'_', Host}, _ = '_'},
|
||||||
|
[],
|
||||||
|
['$_']}]) of
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
?ERROR_MSG("~p", [Reason]),
|
?ERROR_MSG("~p", [Reason]),
|
||||||
ok;
|
ok;
|
||||||
@ -294,6 +299,7 @@ load_permanent_rooms(Access) ->
|
|||||||
{Room, Host} = R#muc_room.name_host,
|
{Room, Host} = R#muc_room.name_host,
|
||||||
{ok, Pid} = mod_muc_room:start(
|
{ok, Pid} = mod_muc_room:start(
|
||||||
Host,
|
Host,
|
||||||
|
ServerHost,
|
||||||
Access,
|
Access,
|
||||||
Room,
|
Room,
|
||||||
R#muc_room.opts),
|
R#muc_room.opts),
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
|
|
||||||
%% External exports
|
%% External exports
|
||||||
-export([start/5,
|
-export([start/6,
|
||||||
start/4,
|
start/5,
|
||||||
route/4]).
|
route/4]).
|
||||||
|
|
||||||
%% gen_fsm callbacks
|
%% gen_fsm callbacks
|
||||||
@ -59,6 +59,7 @@
|
|||||||
|
|
||||||
-record(state, {room,
|
-record(state, {room,
|
||||||
host,
|
host,
|
||||||
|
server_host,
|
||||||
access,
|
access,
|
||||||
jid,
|
jid,
|
||||||
config = #config{},
|
config = #config{},
|
||||||
@ -82,11 +83,12 @@
|
|||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% API
|
%%% API
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
start(Host, Access, Room, Creator, Nick) ->
|
start(Host, ServerHost, Access, Room, Creator, Nick) ->
|
||||||
gen_fsm:start(?MODULE, [Host, Access, Room, Creator, Nick], ?FSMOPTS).
|
gen_fsm:start(?MODULE, [Host, ServerHost, Access, Room, Creator, Nick],
|
||||||
|
?FSMOPTS).
|
||||||
|
|
||||||
start(Host, Access, Room, Opts) ->
|
start(Host, ServerHost, Access, Room, Opts) ->
|
||||||
gen_fsm:start(?MODULE, [Host, Access, Room, Opts], ?FSMOPTS).
|
gen_fsm:start(?MODULE, [Host, ServerHost, Access, Room, Opts], ?FSMOPTS).
|
||||||
|
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% Callback functions from gen_fsm
|
%%% Callback functions from gen_fsm
|
||||||
@ -99,16 +101,18 @@ start(Host, Access, Room, Opts) ->
|
|||||||
%% ignore |
|
%% ignore |
|
||||||
%% {stop, StopReason}
|
%% {stop, StopReason}
|
||||||
%%----------------------------------------------------------------------
|
%%----------------------------------------------------------------------
|
||||||
init([Host, Access, Room, Creator, Nick]) ->
|
init([Host, ServerHost, Access, Room, Creator, Nick]) ->
|
||||||
State = set_affiliation(Creator, owner,
|
State = set_affiliation(Creator, owner,
|
||||||
#state{host = Host,
|
#state{host = Host,
|
||||||
|
server_host = ServerHost,
|
||||||
access = Access,
|
access = Access,
|
||||||
room = Room,
|
room = Room,
|
||||||
jid = jlib:make_jid(Room, Host, ""),
|
jid = jlib:make_jid(Room, Host, ""),
|
||||||
just_created = true}),
|
just_created = true}),
|
||||||
{ok, normal_state, State};
|
{ok, normal_state, State};
|
||||||
init([Host, Access, Room, Opts]) ->
|
init([Host, ServerHost, Access, Room, Opts]) ->
|
||||||
State = set_opts(Opts, #state{host = Host,
|
State = set_opts(Opts, #state{host = Host,
|
||||||
|
server_host = ServerHost,
|
||||||
access = Access,
|
access = Access,
|
||||||
room = Room,
|
room = Room,
|
||||||
jid = jlib:make_jid(Room, Host, "")}),
|
jid = jlib:make_jid(Room, Host, "")}),
|
||||||
@ -652,7 +656,8 @@ handle_info(_Info, StateName, StateData) ->
|
|||||||
%% Returns: any
|
%% Returns: any
|
||||||
%%----------------------------------------------------------------------
|
%%----------------------------------------------------------------------
|
||||||
terminate(_Reason, _StateName, StateData) ->
|
terminate(_Reason, _StateName, StateData) ->
|
||||||
mod_muc:room_destroyed(StateData#state.host, StateData#state.room),
|
mod_muc:room_destroyed(StateData#state.host, StateData#state.room,
|
||||||
|
StateData#state.server_host),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
@ -732,7 +737,7 @@ set_affiliation_and_reason(JID, Affiliation, Reason, StateData) ->
|
|||||||
get_affiliation(JID, StateData) ->
|
get_affiliation(JID, StateData) ->
|
||||||
{_AccessRoute, _AccessCreate, AccessAdmin} = StateData#state.access,
|
{_AccessRoute, _AccessCreate, AccessAdmin} = StateData#state.access,
|
||||||
Res =
|
Res =
|
||||||
case acl:match_rule(AccessAdmin, JID) of
|
case acl:match_rule(StateData#state.server_host, AccessAdmin, JID) of
|
||||||
allow ->
|
allow ->
|
||||||
owner;
|
owner;
|
||||||
_ ->
|
_ ->
|
||||||
|
@ -11,9 +11,9 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1,
|
-export([start/2,
|
||||||
init/0,
|
init/0,
|
||||||
stop/0,
|
stop/1,
|
||||||
store_packet/3,
|
store_packet/3,
|
||||||
resend_offline_messages/2,
|
resend_offline_messages/2,
|
||||||
pop_offline_messages/3,
|
pop_offline_messages/3,
|
||||||
@ -29,21 +29,22 @@
|
|||||||
-define(PROCNAME, ejabberd_offline).
|
-define(PROCNAME, ejabberd_offline).
|
||||||
-define(OFFLINE_TABLE_LOCK_THRESHOLD, 1000).
|
-define(OFFLINE_TABLE_LOCK_THRESHOLD, 1000).
|
||||||
|
|
||||||
start(_) ->
|
start(Host, _Opts) ->
|
||||||
mnesia:create_table(offline_msg,
|
mnesia:create_table(offline_msg,
|
||||||
[{disc_only_copies, [node()]},
|
[{disc_only_copies, [node()]},
|
||||||
{type, bag},
|
{type, bag},
|
||||||
{attributes, record_info(fields, offline_msg)}]),
|
{attributes, record_info(fields, offline_msg)}]),
|
||||||
update_table(),
|
update_table(),
|
||||||
ejabberd_hooks:add(offline_message_hook,
|
ejabberd_hooks:add(offline_message_hook, Host,
|
||||||
?MODULE, store_packet, 50),
|
?MODULE, store_packet, 50),
|
||||||
ejabberd_hooks:add(offline_subscription_hook,
|
ejabberd_hooks:add(offline_subscription_hook, Host,
|
||||||
?MODULE, store_packet, 50),
|
?MODULE, store_packet, 50),
|
||||||
ejabberd_hooks:add(resend_offline_messages_hook,
|
ejabberd_hooks:add(resend_offline_messages_hook, Host,
|
||||||
?MODULE, pop_offline_messages, 50),
|
?MODULE, pop_offline_messages, 50),
|
||||||
ejabberd_hooks:add(remove_user,
|
ejabberd_hooks:add(remove_user, Host,
|
||||||
?MODULE, remove_user, 50),
|
?MODULE, remove_user, 50),
|
||||||
register(?PROCNAME, spawn(?MODULE, init, [])).
|
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
|
spawn(?MODULE, init, [])).
|
||||||
|
|
||||||
init() ->
|
init() ->
|
||||||
loop().
|
loop().
|
||||||
@ -79,17 +80,18 @@ receive_all(Msgs) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
ejabberd_hooks:delete(offline_message_hook,
|
ejabberd_hooks:delete(offline_message_hook, Host,
|
||||||
?MODULE, store_packet, 50),
|
?MODULE, store_packet, 50),
|
||||||
ejabberd_hooks:delete(offline_subscription_hook,
|
ejabberd_hooks:delete(offline_subscription_hook, Host,
|
||||||
?MODULE, store_packet, 50),
|
?MODULE, store_packet, 50),
|
||||||
ejabberd_hooks:delete(resend_offline_messages_hook,
|
ejabberd_hooks:delete(resend_offline_messages_hook, Host,
|
||||||
?MODULE, pop_offline_messages, 50),
|
?MODULE, pop_offline_messages, 50),
|
||||||
ejabberd_hooks:delete(remove_user,
|
ejabberd_hooks:delete(remove_user, Host,
|
||||||
?MODULE, remove_user, 50),
|
?MODULE, remove_user, 50),
|
||||||
exit(whereis(?PROCNAME), stop),
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
{wait, ?PROCNAME}.
|
exit(whereis(Proc), stop),
|
||||||
|
{wait, Proc}.
|
||||||
|
|
||||||
store_packet(From, To, Packet) ->
|
store_packet(From, To, Packet) ->
|
||||||
Type = xml:get_tag_attr_s("type", Packet),
|
Type = xml:get_tag_attr_s("type", Packet),
|
||||||
|
@ -11,9 +11,9 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1,
|
-export([start/2,
|
||||||
init/0,
|
init/0,
|
||||||
stop/0,
|
stop/1,
|
||||||
store_packet/3,
|
store_packet/3,
|
||||||
pop_offline_messages/2,
|
pop_offline_messages/2,
|
||||||
remove_user/1]).
|
remove_user/1]).
|
||||||
@ -26,16 +26,16 @@
|
|||||||
-define(PROCNAME, ejabberd_offline).
|
-define(PROCNAME, ejabberd_offline).
|
||||||
-define(OFFLINE_TABLE_LOCK_THRESHOLD, 1000).
|
-define(OFFLINE_TABLE_LOCK_THRESHOLD, 1000).
|
||||||
|
|
||||||
start(_) ->
|
start(Host, _Opts) ->
|
||||||
% TODO: remove
|
% TODO: remove
|
||||||
ejabberd_odbc:start(),
|
ejabberd_odbc:start(),
|
||||||
ejabberd_hooks:add(offline_message_hook,
|
ejabberd_hooks:add(offline_message_hook, Host,
|
||||||
?MODULE, store_packet, 50),
|
?MODULE, store_packet, 50),
|
||||||
ejabberd_hooks:add(offline_subscription_hook,
|
ejabberd_hooks:add(offline_subscription_hook, Host,
|
||||||
?MODULE, store_packet, 50),
|
?MODULE, store_packet, 50),
|
||||||
ejabberd_hooks:add(resend_offline_messages_hook,
|
ejabberd_hooks:add(resend_offline_messages_hook, Host,
|
||||||
?MODULE, pop_offline_messages, 50),
|
?MODULE, pop_offline_messages, 50),
|
||||||
ejabberd_hooks:add(remove_user,
|
ejabberd_hooks:add(remove_user, Host,
|
||||||
?MODULE, remove_user, 50),
|
?MODULE, remove_user, 50),
|
||||||
register(?PROCNAME, spawn(?MODULE, init, [])).
|
register(?PROCNAME, spawn(?MODULE, init, [])).
|
||||||
|
|
||||||
@ -95,14 +95,14 @@ receive_all(Msgs) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
ejabberd_hooks:delete(offline_message_hook,
|
ejabberd_hooks:delete(offline_message_hook, Host,
|
||||||
?MODULE, store_packet, 50),
|
?MODULE, store_packet, 50),
|
||||||
ejabberd_hooks:delete(offline_subscription_hook,
|
ejabberd_hooks:delete(offline_subscription_hook, Host,
|
||||||
?MODULE, store_packet, 50),
|
?MODULE, store_packet, 50),
|
||||||
ejabberd_hooks:delete(resend_offline_messages_hook,
|
ejabberd_hooks:delete(resend_offline_messages_hook, Host,
|
||||||
?MODULE, pop_offline_messages, 50),
|
?MODULE, pop_offline_messages, 50),
|
||||||
ejabberd_hooks:delete(remove_user,
|
ejabberd_hooks:delete(remove_user, Host,
|
||||||
?MODULE, remove_user, 50),
|
?MODULE, remove_user, 50),
|
||||||
exit(whereis(?PROCNAME), stop),
|
exit(whereis(?PROCNAME), stop),
|
||||||
ok.
|
ok.
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1, stop/0,
|
-export([start/2, stop/1,
|
||||||
process_iq/3,
|
process_iq/3,
|
||||||
process_iq_set/3,
|
process_iq_set/3,
|
||||||
process_iq_get/4,
|
process_iq_get/4,
|
||||||
@ -42,16 +42,16 @@
|
|||||||
-record(userlist, {name = none, list = []}).
|
-record(userlist, {name = none, list = []}).
|
||||||
|
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
mnesia:create_table(privacy, [{disc_copies, [node()]},
|
mnesia:create_table(privacy, [{disc_copies, [node()]},
|
||||||
{attributes, record_info(fields, privacy)}]),
|
{attributes, record_info(fields, privacy)}]),
|
||||||
update_table(),
|
update_table(),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_PRIVACY,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY,
|
||||||
?MODULE, process_iq, IQDisc).
|
?MODULE, process_iq, IQDisc).
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_PRIVACY).
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY).
|
||||||
|
|
||||||
process_iq(From, _To, IQ) ->
|
process_iq(From, _To, IQ) ->
|
||||||
#iq{type = Type, sub_el = SubEl} = IQ,
|
#iq{type = Type, sub_el = SubEl} = IQ,
|
||||||
@ -555,32 +555,32 @@ check_packet(User, Server,
|
|||||||
LJID = jlib:jid_tolower(From),
|
LJID = jlib:jid_tolower(From),
|
||||||
{Subscription, Groups} =
|
{Subscription, Groups} =
|
||||||
ejabberd_hooks:run_fold(
|
ejabberd_hooks:run_fold(
|
||||||
roster_get_jid_info, {none, []},
|
roster_get_jid_info, jlib:nameprep(Server),
|
||||||
[User, Server, LJID]),
|
{none, []}, [User, Server, LJID]),
|
||||||
check_packet_aux(List, message,
|
check_packet_aux(List, message,
|
||||||
LJID, Subscription, Groups);
|
LJID, Subscription, Groups);
|
||||||
{iq, in} ->
|
{iq, in} ->
|
||||||
LJID = jlib:jid_tolower(From),
|
LJID = jlib:jid_tolower(From),
|
||||||
{Subscription, Groups} =
|
{Subscription, Groups} =
|
||||||
ejabberd_hooks:run_fold(
|
ejabberd_hooks:run_fold(
|
||||||
roster_get_jid_info, {none, []},
|
roster_get_jid_info, jlib:nameprep(Server),
|
||||||
[User, Server, LJID]),
|
{none, []}, [User, Server, LJID]),
|
||||||
check_packet_aux(List, iq,
|
check_packet_aux(List, iq,
|
||||||
LJID, Subscription, Groups);
|
LJID, Subscription, Groups);
|
||||||
{presence, in} ->
|
{presence, in} ->
|
||||||
LJID = jlib:jid_tolower(From),
|
LJID = jlib:jid_tolower(From),
|
||||||
{Subscription, Groups} =
|
{Subscription, Groups} =
|
||||||
ejabberd_hooks:run_fold(
|
ejabberd_hooks:run_fold(
|
||||||
roster_get_jid_info, {none, []},
|
roster_get_jid_info, jlib:nameprep(Server),
|
||||||
[User, Server, LJID]),
|
{none, []}, [User, Server, LJID]),
|
||||||
check_packet_aux(List, presence_in,
|
check_packet_aux(List, presence_in,
|
||||||
LJID, Subscription, Groups);
|
LJID, Subscription, Groups);
|
||||||
{presence, out} ->
|
{presence, out} ->
|
||||||
LJID = jlib:jid_tolower(To),
|
LJID = jlib:jid_tolower(To),
|
||||||
{Subscription, Groups} =
|
{Subscription, Groups} =
|
||||||
ejabberd_hooks:run_fold(
|
ejabberd_hooks:run_fold(
|
||||||
roster_get_jid_info, {none, []},
|
roster_get_jid_info, jlib:nameprep(Server),
|
||||||
[User, Server, LJID]),
|
{none, []}, [User, Server, LJID]),
|
||||||
check_packet_aux(List, presence_out,
|
check_packet_aux(List, presence_out,
|
||||||
LJID, Subscription, Groups);
|
LJID, Subscription, Groups);
|
||||||
_ ->
|
_ ->
|
||||||
@ -592,12 +592,12 @@ check_packet_aux([], _PType, _JID, _Subscription, _Groups) ->
|
|||||||
allow;
|
allow;
|
||||||
check_packet_aux([Item | List], PType, JID, Subscription, Groups) ->
|
check_packet_aux([Item | List], PType, JID, Subscription, Groups) ->
|
||||||
#listitem{type = Type, value = Value, action = Action} = Item,
|
#listitem{type = Type, value = Value, action = Action} = Item,
|
||||||
|
case is_ptype_match(Item, PType) of
|
||||||
|
true ->
|
||||||
case Type of
|
case Type of
|
||||||
none ->
|
none ->
|
||||||
Action;
|
Action;
|
||||||
_ ->
|
_ ->
|
||||||
case is_ptype_match(Item, PType) of
|
|
||||||
true ->
|
|
||||||
case is_type_match(Type, Value,
|
case is_type_match(Type, Value,
|
||||||
JID, Subscription, Groups) of
|
JID, Subscription, Groups) of
|
||||||
true ->
|
true ->
|
||||||
@ -605,10 +605,10 @@ check_packet_aux([Item | List], PType, JID, Subscription, Groups) ->
|
|||||||
false ->
|
false ->
|
||||||
check_packet_aux(List, PType,
|
check_packet_aux(List, PType,
|
||||||
JID, Subscription, Groups)
|
JID, Subscription, Groups)
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
false ->
|
false ->
|
||||||
check_packet_aux(List, PType, JID, Subscription, Groups)
|
check_packet_aux(List, PType, JID, Subscription, Groups)
|
||||||
end
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1,
|
-export([start/2,
|
||||||
stop/0,
|
stop/1,
|
||||||
process_sm_iq/3,
|
process_sm_iq/3,
|
||||||
remove_user/2]).
|
remove_user/2]).
|
||||||
|
|
||||||
@ -22,21 +22,21 @@
|
|||||||
|
|
||||||
-record(private_storage, {usns, xml}).
|
-record(private_storage, {usns, xml}).
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
mnesia:create_table(private_storage,
|
mnesia:create_table(private_storage,
|
||||||
[{disc_only_copies, [node()]},
|
[{disc_only_copies, [node()]},
|
||||||
{attributes, record_info(fields, private_storage)}]),
|
{attributes, record_info(fields, private_storage)}]),
|
||||||
update_table(),
|
update_table(),
|
||||||
ejabberd_hooks:add(remove_user,
|
ejabberd_hooks:add(remove_user, Host,
|
||||||
?MODULE, remove_user, 50),
|
?MODULE, remove_user, 50),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_PRIVATE,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE,
|
||||||
?MODULE, process_sm_iq, IQDisc).
|
?MODULE, process_sm_iq, IQDisc).
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
ejabberd_hooks:delete(remove_user,
|
ejabberd_hooks:delete(remove_user, Host,
|
||||||
?MODULE, remove_user, 50),
|
?MODULE, remove_user, 50),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_PRIVATE).
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE).
|
||||||
|
|
||||||
|
|
||||||
process_sm_iq(From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
process_sm_iq(From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
||||||
|
@ -12,10 +12,10 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1,
|
-export([start/2,
|
||||||
init/3,
|
init/4,
|
||||||
loop/2,
|
loop/2,
|
||||||
stop/0,
|
stop/1,
|
||||||
system_continue/3,
|
system_continue/3,
|
||||||
system_terminate/4,
|
system_terminate/4,
|
||||||
system_code_change/4]).
|
system_code_change/4]).
|
||||||
@ -37,37 +37,34 @@
|
|||||||
|
|
||||||
-define(PROCNAME, ejabberd_mod_pubsub).
|
-define(PROCNAME, ejabberd_mod_pubsub).
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
mnesia:create_table(pubsub_node,
|
mnesia:create_table(pubsub_node,
|
||||||
[{disc_only_copies, [node()]},
|
[{disc_only_copies, [node()]},
|
||||||
{attributes, record_info(fields, pubsub_node)}]),
|
{attributes, record_info(fields, pubsub_node)}]),
|
||||||
Hosts = gen_mod:get_hosts(Opts, "pubsub."),
|
MyHost = gen_mod:get_opt(host, Opts, "pubsub." ++ Host),
|
||||||
Host = hd(Hosts),
|
update_table(MyHost),
|
||||||
update_table(Host),
|
|
||||||
mnesia:add_table_index(pubsub_node, host_parent),
|
mnesia:add_table_index(pubsub_node, host_parent),
|
||||||
ServedHosts = gen_mod:get_opt(served_hosts, Opts, []),
|
ServedHosts = gen_mod:get_opt(served_hosts, Opts, []),
|
||||||
register(?PROCNAME,
|
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
proc_lib:spawn_link(?MODULE, init, [Hosts, ServedHosts, self()])).
|
proc_lib:spawn_link(?MODULE, init,
|
||||||
|
[MyHost, Host, ServedHosts, self()])).
|
||||||
|
|
||||||
|
|
||||||
-define(MYJID, #jid{user = "", server = Host, resource = "",
|
-define(MYJID, #jid{user = "", server = Host, resource = "",
|
||||||
luser = "", lserver = Host, lresource = ""}).
|
luser = "", lserver = Host, lresource = ""}).
|
||||||
|
|
||||||
init(Hosts, ServedHosts, Parent) ->
|
init(Host, ServerHost, ServedHosts, Parent) ->
|
||||||
ejabberd_router:register_routes(Hosts),
|
ejabberd_router:register_route(Host),
|
||||||
lists:foreach(
|
|
||||||
fun(Host) ->
|
|
||||||
create_new_node(Host, ["pubsub"], ?MYJID),
|
create_new_node(Host, ["pubsub"], ?MYJID),
|
||||||
create_new_node(Host, ["pubsub", "nodes"], ?MYJID),
|
create_new_node(Host, ["pubsub", "nodes"], ?MYJID),
|
||||||
create_new_node(Host, ["home"], ?MYJID),
|
create_new_node(Host, ["home"], ?MYJID),
|
||||||
create_new_node(Host, ["home", find_my_host(Host)], ?MYJID),
|
create_new_node(Host, ["home", ServerHost], ?MYJID),
|
||||||
lists:foreach(fun(H) ->
|
lists:foreach(fun(H) ->
|
||||||
create_new_node(Host, ["home", H], ?MYJID)
|
create_new_node(Host, ["home", H], ?MYJID)
|
||||||
end, ServedHosts)
|
end, ServedHosts),
|
||||||
end, Hosts),
|
loop(Host, Parent).
|
||||||
loop(Hosts, Parent).
|
|
||||||
|
|
||||||
loop(Hosts, Parent) ->
|
loop(Host, Parent) ->
|
||||||
receive
|
receive
|
||||||
{route, From, To, Packet} ->
|
{route, From, To, Packet} ->
|
||||||
case catch do_route(To#jid.lserver, From, To, Packet) of
|
case catch do_route(To#jid.lserver, From, To, Packet) of
|
||||||
@ -76,19 +73,19 @@ loop(Hosts, Parent) ->
|
|||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
loop(Hosts, Parent);
|
loop(Host, Parent);
|
||||||
{room_destroyed, Room} ->
|
{room_destroyed, Room} ->
|
||||||
ets:delete(muc_online_room, Room),
|
ets:delete(muc_online_room, Room),
|
||||||
loop(Hosts, Parent);
|
loop(Host, Parent);
|
||||||
stop ->
|
stop ->
|
||||||
ejabberd_router:unregister_routes(Hosts),
|
ejabberd_router:unregister_route(Host),
|
||||||
ok;
|
ok;
|
||||||
reload ->
|
reload ->
|
||||||
?MODULE:loop(Hosts, Parent);
|
?MODULE:loop(Host, Parent);
|
||||||
{system, From, Request} ->
|
{system, From, Request} ->
|
||||||
sys:handle_system_msg(Request, From, Parent, ?MODULE, [], Hosts);
|
sys:handle_system_msg(Request, From, Parent, ?MODULE, [], Host);
|
||||||
_ ->
|
_ ->
|
||||||
loop(Hosts, Parent)
|
loop(Host, Parent)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
@ -202,9 +199,10 @@ do_route(Host, From, To, Packet) ->
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
?PROCNAME ! stop,
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
{wait, ?PROCNAME}.
|
Proc ! stop,
|
||||||
|
{wait, Proc}.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1177,26 +1175,6 @@ system_code_change(State, _Mod, Ver, _Extra) ->
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
find_my_host(LServer) ->
|
|
||||||
Parts = string:tokens(LServer, "."),
|
|
||||||
find_my_host(Parts, ?MYHOSTS).
|
|
||||||
|
|
||||||
find_my_host([], _Hosts) ->
|
|
||||||
?MYNAME;
|
|
||||||
find_my_host([_ | Tail] = Parts, Hosts) ->
|
|
||||||
Domain = parts_to_string(Parts),
|
|
||||||
case lists:member(Domain, Hosts) of
|
|
||||||
true ->
|
|
||||||
Domain;
|
|
||||||
false ->
|
|
||||||
find_my_host(Tail, Hosts)
|
|
||||||
end.
|
|
||||||
|
|
||||||
parts_to_string(Parts) ->
|
|
||||||
string:strip(lists:flatten(lists:map(fun(S) -> [S, $.] end, Parts)),
|
|
||||||
right, $.).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
update_table(Host) ->
|
update_table(Host) ->
|
||||||
Fields = record_info(fields, pubsub_node),
|
Fields = record_info(fields, pubsub_node),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% File : mod_register.erl
|
%%% File : mod_register.erl
|
||||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||||
%%% Purpose :
|
%%% Purpose : Inband registration support
|
||||||
%%% Created : 8 Dec 2002 by Alexey Shchepin <alexey@sevcom.net>
|
%%% Created : 8 Dec 2002 by Alexey Shchepin <alexey@sevcom.net>
|
||||||
%%% Id : $Id$
|
%%% Id : $Id$
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
@ -12,24 +12,27 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1, stop/0, process_iq/3]).
|
-export([start/2,
|
||||||
|
stop/1,
|
||||||
|
process_iq/3]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_REGISTER,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_REGISTER,
|
||||||
?MODULE, process_iq, IQDisc),
|
?MODULE, process_iq, IQDisc),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_REGISTER,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_REGISTER,
|
||||||
?MODULE, process_iq, IQDisc),
|
?MODULE, process_iq, IQDisc),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_REGISTER),
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_REGISTER),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_REGISTER).
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_REGISTER).
|
||||||
|
|
||||||
process_iq(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
process_iq(From, To,
|
||||||
|
#iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
||||||
case Type of
|
case Type of
|
||||||
set ->
|
set ->
|
||||||
UTag = xml:get_subtag(SubEl, "username"),
|
UTag = xml:get_subtag(SubEl, "username"),
|
||||||
@ -123,8 +126,8 @@ try_register(User, Server, Password) ->
|
|||||||
{error, ?ERR_BAD_REQUEST};
|
{error, ?ERR_BAD_REQUEST};
|
||||||
_ ->
|
_ ->
|
||||||
JID = jlib:make_jid(User, Server, ""),
|
JID = jlib:make_jid(User, Server, ""),
|
||||||
Access = gen_mod:get_module_opt(?MODULE, access, all),
|
Access = gen_mod:get_module_opt(Server, ?MODULE, access, all),
|
||||||
case acl:match_rule(Access, JID) of
|
case acl:match_rule(Server, Access, JID) of
|
||||||
deny ->
|
deny ->
|
||||||
{error, ?ERR_CONFLICT};
|
{error, ?ERR_CONFLICT};
|
||||||
allow ->
|
allow ->
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1, stop/0,
|
-export([start/2, stop/1,
|
||||||
process_iq/3,
|
process_iq/3,
|
||||||
process_local_iq/3,
|
process_local_iq/3,
|
||||||
get_user_roster/2,
|
get_user_roster/2,
|
||||||
@ -28,41 +28,41 @@
|
|||||||
-include("mod_roster.hrl").
|
-include("mod_roster.hrl").
|
||||||
|
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
mnesia:create_table(roster,[{disc_copies, [node()]},
|
mnesia:create_table(roster,[{disc_copies, [node()]},
|
||||||
{attributes, record_info(fields, roster)}]),
|
{attributes, record_info(fields, roster)}]),
|
||||||
update_table(),
|
update_table(),
|
||||||
mnesia:add_table_index(roster, us),
|
mnesia:add_table_index(roster, us),
|
||||||
ejabberd_hooks:add(roster_get,
|
ejabberd_hooks:add(roster_get, Host,
|
||||||
?MODULE, get_user_roster, 50),
|
?MODULE, get_user_roster, 50),
|
||||||
ejabberd_hooks:add(roster_in_subscription,
|
ejabberd_hooks:add(roster_in_subscription, Host,
|
||||||
?MODULE, in_subscription, 50),
|
?MODULE, in_subscription, 50),
|
||||||
ejabberd_hooks:add(roster_out_subscription,
|
ejabberd_hooks:add(roster_out_subscription, Host,
|
||||||
?MODULE, out_subscription, 50),
|
?MODULE, out_subscription, 50),
|
||||||
ejabberd_hooks:add(roster_get_subscription_lists,
|
ejabberd_hooks:add(roster_get_subscription_lists, Host,
|
||||||
?MODULE, get_subscription_lists, 50),
|
?MODULE, get_subscription_lists, 50),
|
||||||
ejabberd_hooks:add(roster_get_jid_info,
|
ejabberd_hooks:add(roster_get_jid_info, Host,
|
||||||
?MODULE, get_jid_info, 50),
|
?MODULE, get_jid_info, 50),
|
||||||
ejabberd_hooks:add(remove_user,
|
ejabberd_hooks:add(remove_user, Host,
|
||||||
?MODULE, remove_user, 50),
|
?MODULE, remove_user, 50),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_ROSTER,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER,
|
||||||
?MODULE, process_iq, IQDisc).
|
?MODULE, process_iq, IQDisc).
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
ejabberd_hooks:delete(roster_get,
|
ejabberd_hooks:delete(roster_get, Host,
|
||||||
?MODULE, get_user_roster, 50),
|
?MODULE, get_user_roster, 50),
|
||||||
ejabberd_hooks:delete(roster_in_subscription,
|
ejabberd_hooks:delete(roster_in_subscription, Host,
|
||||||
?MODULE, in_subscription, 50),
|
?MODULE, in_subscription, 50),
|
||||||
ejabberd_hooks:delete(roster_out_subscription,
|
ejabberd_hooks:delete(roster_out_subscription, Host,
|
||||||
?MODULE, out_subscription, 50),
|
?MODULE, out_subscription, 50),
|
||||||
ejabberd_hooks:delete(roster_get_subscription_lists,
|
ejabberd_hooks:delete(roster_get_subscription_lists, Host,
|
||||||
?MODULE, get_subscription_lists, 50),
|
?MODULE, get_subscription_lists, 50),
|
||||||
ejabberd_hooks:delete(roster_get_jid_info,
|
ejabberd_hooks:delete(roster_get_jid_info, Host,
|
||||||
?MODULE, get_jid_info, 50),
|
?MODULE, get_jid_info, 50),
|
||||||
ejabberd_hooks:delete(remove_user,
|
ejabberd_hooks:delete(remove_user, Host,
|
||||||
?MODULE, remove_user, 50),
|
?MODULE, remove_user, 50),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_ROSTER).
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ROSTER).
|
||||||
|
|
||||||
|
|
||||||
-define(PSI_ROSTER_WORKAROUND, true).
|
-define(PSI_ROSTER_WORKAROUND, true).
|
||||||
@ -106,11 +106,11 @@ process_local_iq(From, To, #iq{type = Type} = IQ) ->
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
process_iq_get(From, _To, #iq{sub_el = SubEl} = IQ) ->
|
process_iq_get(From, To, #iq{sub_el = SubEl} = IQ) ->
|
||||||
LUser = From#jid.luser,
|
LUser = From#jid.luser,
|
||||||
LServer = From#jid.lserver,
|
LServer = From#jid.lserver,
|
||||||
US = {LUser, LServer},
|
US = {LUser, LServer},
|
||||||
case catch ejabberd_hooks:run_fold(roster_get, [], [US]) of
|
case catch ejabberd_hooks:run_fold(roster_get, To#jid.lserver, [], [US]) of
|
||||||
Items when is_list(Items) ->
|
Items when is_list(Items) ->
|
||||||
XItems = lists:map(fun item_to_xml/1, Items),
|
XItems = lists:map(fun item_to_xml/1, Items),
|
||||||
IQ#iq{type = result,
|
IQ#iq{type = result,
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1, stop/0,
|
-export([start/2, stop/1,
|
||||||
process_iq/3,
|
process_iq/3,
|
||||||
process_local_iq/3,
|
process_local_iq/3,
|
||||||
get_subscription_lists/2,
|
get_subscription_lists/2,
|
||||||
@ -31,35 +31,35 @@
|
|||||||
subscription = none,
|
subscription = none,
|
||||||
ask = none}).
|
ask = none}).
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
ejabberd_hooks:add(roster_out_subscription,
|
ejabberd_hooks:add(roster_out_subscription, Host,
|
||||||
?MODULE, out_subscription, 50),
|
?MODULE, out_subscription, 50),
|
||||||
ejabberd_hooks:add(roster_in_subscription,
|
ejabberd_hooks:add(roster_in_subscription, Host,
|
||||||
?MODULE, in_subscription, 50),
|
?MODULE, in_subscription, 50),
|
||||||
ejabberd_hooks:add(roster_out_subscription,
|
ejabberd_hooks:add(roster_out_subscription, Host,
|
||||||
?MODULE, out_subscription, 50),
|
?MODULE, out_subscription, 50),
|
||||||
ejabberd_hooks:add(roster_get_subscription_lists,
|
ejabberd_hooks:add(roster_get_subscription_lists, Host,
|
||||||
?MODULE, get_subscription_lists, 50),
|
?MODULE, get_subscription_lists, 50),
|
||||||
ejabberd_hooks:add(roster_get_jid_info,
|
ejabberd_hooks:add(roster_get_jid_info, Host,
|
||||||
?MODULE, get_jid_info, 50),
|
?MODULE, get_jid_info, 50),
|
||||||
ejabberd_hooks:add(remove_user,
|
ejabberd_hooks:add(remove_user, Host,
|
||||||
?MODULE, remove_user, 50),
|
?MODULE, remove_user, 50),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_ROSTER,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER,
|
||||||
?MODULE, process_iq, IQDisc).
|
?MODULE, process_iq, IQDisc).
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
ejabberd_hooks:delete(roster_in_subscription,
|
ejabberd_hooks:delete(roster_in_subscription, Host,
|
||||||
?MODULE, in_subscription, 50),
|
?MODULE, in_subscription, 50),
|
||||||
ejabberd_hooks:delete(roster_out_subscription,
|
ejabberd_hooks:delete(roster_out_subscription, Host,
|
||||||
?MODULE, out_subscription, 50),
|
?MODULE, out_subscription, 50),
|
||||||
ejabberd_hooks:delete(roster_get_subscription_lists,
|
ejabberd_hooks:delete(roster_get_subscription_lists, Host,
|
||||||
?MODULE, get_subscription_lists, 50),
|
?MODULE, get_subscription_lists, 50),
|
||||||
ejabberd_hooks:delete(roster_get_jid_info,
|
ejabberd_hooks:delete(roster_get_jid_info, Host,
|
||||||
?MODULE, get_jid_info, 50),
|
?MODULE, get_jid_info, 50),
|
||||||
ejabberd_hooks:delete(remove_user,
|
ejabberd_hooks:delete(remove_user, Host,
|
||||||
?MODULE, remove_user, 50),
|
?MODULE, remove_user, 50),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_ROSTER).
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ROSTER).
|
||||||
|
|
||||||
|
|
||||||
-define(PSI_ROSTER_WORKAROUND, true).
|
-define(PSI_ROSTER_WORKAROUND, true).
|
||||||
|
@ -11,25 +11,25 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1,
|
-export([start/2,
|
||||||
stop/0,
|
stop/1,
|
||||||
log_user_send/3,
|
log_user_send/3,
|
||||||
log_user_receive/4]).
|
log_user_receive/4]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
|
|
||||||
start(_) ->
|
start(Host, _Opts) ->
|
||||||
ejabberd_hooks:add(user_send_packet,
|
ejabberd_hooks:add(user_send_packet, Host,
|
||||||
?MODULE, log_user_send, 50),
|
?MODULE, log_user_send, 50),
|
||||||
ejabberd_hooks:add(user_receive_packet,
|
ejabberd_hooks:add(user_receive_packet, Host,
|
||||||
?MODULE, log_user_receive, 50),
|
?MODULE, log_user_receive, 50),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
ejabberd_hooks:delete(user_send_packet,
|
ejabberd_hooks:delete(user_send_packet, Host,
|
||||||
?MODULE, log_user_send, 50),
|
?MODULE, log_user_send, 50),
|
||||||
ejabberd_hooks:delete(user_receive_packet,
|
ejabberd_hooks:delete(user_receive_packet, Host,
|
||||||
?MODULE, log_user_receive, 50),
|
?MODULE, log_user_receive, 50),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
@ -41,9 +41,10 @@ log_user_receive(_JID, From, To, Packet) ->
|
|||||||
|
|
||||||
|
|
||||||
log_packet(From, To, {xmlelement, Name, Attrs, Els}) ->
|
log_packet(From, To, {xmlelement, Name, Attrs, Els}) ->
|
||||||
Loggers = gen_mod:get_module_opt(?MODULE, loggers, []),
|
Host = From#jid.lserver,
|
||||||
ServerJID = #jid{user = "", server = ?MYNAME, resource = "",
|
Loggers = gen_mod:get_module_opt(Host, ?MODULE, loggers, []),
|
||||||
luser = "", lserver = ?MYNAME, lresource = ""},
|
ServerJID = #jid{user = "", server = Host, resource = "",
|
||||||
|
luser = "", lserver = Host, lresource = ""},
|
||||||
NewAttrs = jlib:replace_from_to_attrs(jlib:jid_to_string(From),
|
NewAttrs = jlib:replace_from_to_attrs(jlib:jid_to_string(From),
|
||||||
jlib:jid_to_string(To),
|
jlib:jid_to_string(To),
|
||||||
Attrs),
|
Attrs),
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1, stop/0,
|
-export([start/2, stop/1,
|
||||||
get_user_roster/2,
|
get_user_roster/2,
|
||||||
get_subscription_lists/3,
|
get_subscription_lists/3,
|
||||||
get_jid_info/4,
|
get_jid_info/4,
|
||||||
@ -35,7 +35,7 @@
|
|||||||
-record(sr_group, {group_host, opts}).
|
-record(sr_group, {group_host, opts}).
|
||||||
-record(sr_user, {us, group_host}).
|
-record(sr_user, {us, group_host}).
|
||||||
|
|
||||||
start(_Opts) ->
|
start(Host, _Opts) ->
|
||||||
mnesia:create_table(sr_group,
|
mnesia:create_table(sr_group,
|
||||||
[{disc_copies, [node()]},
|
[{disc_copies, [node()]},
|
||||||
{attributes, record_info(fields, sr_group)}]),
|
{attributes, record_info(fields, sr_group)}]),
|
||||||
@ -44,31 +44,31 @@ start(_Opts) ->
|
|||||||
{type, bag},
|
{type, bag},
|
||||||
{attributes, record_info(fields, sr_user)}]),
|
{attributes, record_info(fields, sr_user)}]),
|
||||||
mnesia:add_table_index(sr_user, group_host),
|
mnesia:add_table_index(sr_user, group_host),
|
||||||
ejabberd_hooks:add(roster_get,
|
ejabberd_hooks:add(roster_get, Host,
|
||||||
?MODULE, get_user_roster, 70),
|
?MODULE, get_user_roster, 70),
|
||||||
ejabberd_hooks:add(roster_in_subscription,
|
ejabberd_hooks:add(roster_in_subscription, Host,
|
||||||
?MODULE, in_subscription, 30),
|
?MODULE, in_subscription, 30),
|
||||||
ejabberd_hooks:add(roster_out_subscription,
|
ejabberd_hooks:add(roster_out_subscription, Host,
|
||||||
?MODULE, out_subscription, 30),
|
?MODULE, out_subscription, 30),
|
||||||
ejabberd_hooks:add(roster_get_subscription_lists,
|
ejabberd_hooks:add(roster_get_subscription_lists, Host,
|
||||||
?MODULE, get_subscription_lists, 70),
|
?MODULE, get_subscription_lists, 70),
|
||||||
ejabberd_hooks:add(roster_get_jid_info,
|
ejabberd_hooks:add(roster_get_jid_info, Host,
|
||||||
?MODULE, get_jid_info, 70).
|
?MODULE, get_jid_info, 70).
|
||||||
%ejabberd_hooks:add(remove_user,
|
%ejabberd_hooks:add(remove_user, Host,
|
||||||
% ?MODULE, remove_user, 50),
|
% ?MODULE, remove_user, 50),
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
ejabberd_hooks:delete(roster_get,
|
ejabberd_hooks:delete(roster_get, Host,
|
||||||
?MODULE, get_user_roster, 70),
|
?MODULE, get_user_roster, 70),
|
||||||
ejabberd_hooks:delete(roster_in_subscription,
|
ejabberd_hooks:delete(roster_in_subscription, Host,
|
||||||
?MODULE, in_subscription, 30),
|
?MODULE, in_subscription, 30),
|
||||||
ejabberd_hooks:delete(roster_out_subscription,
|
ejabberd_hooks:delete(roster_out_subscription, Host,
|
||||||
?MODULE, out_subscription, 30),
|
?MODULE, out_subscription, 30),
|
||||||
ejabberd_hooks:delete(roster_get_subscription_lists,
|
ejabberd_hooks:delete(roster_get_subscription_lists, Host,
|
||||||
?MODULE, get_subscription_lists, 70),
|
?MODULE, get_subscription_lists, 70),
|
||||||
ejabberd_hooks:delete(roster_get_jid_info,
|
ejabberd_hooks:delete(roster_get_jid_info, Host,
|
||||||
?MODULE, get_jid_info, 70).
|
?MODULE, get_jid_info, 70).
|
||||||
%ejabberd_hooks:delete(remove_user,
|
%ejabberd_hooks:delete(remove_user, Host,
|
||||||
% ?MODULE, remove_user, 50),
|
% ?MODULE, remove_user, 50),
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,19 +12,19 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1,
|
-export([start/2,
|
||||||
stop/0,
|
stop/1,
|
||||||
process_local_iq/3]).
|
process_local_iq/3]).
|
||||||
|
|
||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_STATS,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_STATS,
|
||||||
?MODULE, process_local_iq, IQDisc).
|
?MODULE, process_local_iq, IQDisc).
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_STATS).
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_STATS).
|
||||||
|
|
||||||
|
|
||||||
process_local_iq(From, To, #iq{id = ID, type = Type,
|
process_local_iq(From, To, #iq{id = ID, type = Type,
|
||||||
|
@ -12,21 +12,21 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1,
|
-export([start/2,
|
||||||
stop/0,
|
stop/1,
|
||||||
process_local_iq/3]).
|
process_local_iq/3]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
|
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_TIME,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_TIME,
|
||||||
?MODULE, process_local_iq, IQDisc).
|
?MODULE, process_local_iq, IQDisc).
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_TIME).
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_TIME).
|
||||||
|
|
||||||
process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
||||||
case Type of
|
case Type of
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1, init/2, stop/0,
|
-export([start/2, init/2, stop/1,
|
||||||
process_local_iq/3,
|
process_local_iq/3,
|
||||||
process_sm_iq/3,
|
process_sm_iq/3,
|
||||||
reindex_vcards/0,
|
reindex_vcards/0,
|
||||||
@ -40,8 +40,9 @@
|
|||||||
}).
|
}).
|
||||||
-record(vcard, {us, vcard}).
|
-record(vcard, {us, vcard}).
|
||||||
|
|
||||||
|
-define(PROCNAME, ejabberd_mod_vcard).
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
mnesia:create_table(vcard, [{disc_only_copies, [node()]},
|
mnesia:create_table(vcard, [{disc_only_copies, [node()]},
|
||||||
{attributes, record_info(fields, vcard)}]),
|
{attributes, record_info(fields, vcard)}]),
|
||||||
mnesia:create_table(vcard_search,
|
mnesia:create_table(vcard_search,
|
||||||
@ -61,17 +62,18 @@ start(Opts) ->
|
|||||||
mnesia:add_table_index(vcard_search, lorgname),
|
mnesia:add_table_index(vcard_search, lorgname),
|
||||||
mnesia:add_table_index(vcard_search, lorgunit),
|
mnesia:add_table_index(vcard_search, lorgunit),
|
||||||
|
|
||||||
ejabberd_hooks:add(remove_user,
|
ejabberd_hooks:add(remove_user, Host,
|
||||||
?MODULE, remove_user, 50),
|
?MODULE, remove_user, 50),
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_VCARD,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD,
|
||||||
?MODULE, process_local_iq, IQDisc),
|
?MODULE, process_local_iq, IQDisc),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_VCARD,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
|
||||||
?MODULE, process_sm_iq, IQDisc),
|
?MODULE, process_sm_iq, IQDisc),
|
||||||
catch mod_disco:register_sm_feature(?NS_VCARD),
|
catch mod_disco:register_sm_feature(?NS_VCARD),
|
||||||
Hosts = gen_mod:get_hosts(Opts, "vjud."),
|
Hosts = gen_mod:get_hosts(Opts, "vjud."),
|
||||||
Search = gen_mod:get_opt(search, Opts, true),
|
Search = gen_mod:get_opt(search, Opts, true),
|
||||||
register(ejabberd_mod_vcard, spawn(?MODULE, init, [Hosts, Search])).
|
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
|
spawn(?MODULE, init, [Hosts, Search])).
|
||||||
|
|
||||||
|
|
||||||
init(Hosts, Search) ->
|
init(Hosts, Search) ->
|
||||||
@ -100,14 +102,15 @@ loop(Hosts) ->
|
|||||||
loop(Hosts)
|
loop(Hosts)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
ejabberd_hooks:delete(remove_user,
|
ejabberd_hooks:delete(remove_user, Host,
|
||||||
?MODULE, remove_user, 50),
|
?MODULE, remove_user, 50),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_VCARD),
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_VCARD),
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD),
|
||||||
catch mod_disco:unregister_sm_feature(?NS_VCARD),
|
catch mod_disco:unregister_sm_feature(Host, ?NS_VCARD),
|
||||||
ejabberd_mod_vcard ! stop,
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
ok.
|
Proc ! stop,
|
||||||
|
{wait, Proc}.
|
||||||
|
|
||||||
process_local_iq(_From, _To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
process_local_iq(_From, _To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
||||||
case Type of
|
case Type of
|
||||||
@ -463,7 +466,8 @@ record_to_item(R) ->
|
|||||||
|
|
||||||
search(LServer, Data) ->
|
search(LServer, Data) ->
|
||||||
MatchSpec = make_matchspec(LServer, Data),
|
MatchSpec = make_matchspec(LServer, Data),
|
||||||
AllowReturnAll = gen_mod:get_module_opt(?MODULE, allow_return_all, false),
|
AllowReturnAll = gen_mod:get_module_opt(LServer, ?MODULE,
|
||||||
|
allow_return_all, false),
|
||||||
if
|
if
|
||||||
(MatchSpec == #vcard_search{_ = '_'}) and (not AllowReturnAll) ->
|
(MatchSpec == #vcard_search{_ = '_'}) and (not AllowReturnAll) ->
|
||||||
[];
|
[];
|
||||||
@ -474,7 +478,8 @@ search(LServer, Data) ->
|
|||||||
?ERROR_MSG("~p", [Reason]),
|
?ERROR_MSG("~p", [Reason]),
|
||||||
[];
|
[];
|
||||||
Rs ->
|
Rs ->
|
||||||
case gen_mod:get_module_opt(?MODULE, matches, ?JUD_MATCHES) of
|
case gen_mod:get_module_opt(LServer, ?MODULE,
|
||||||
|
matches, ?JUD_MATCHES) of
|
||||||
infinity ->
|
infinity ->
|
||||||
Rs;
|
Rs;
|
||||||
Val when is_integer(Val) and (Val > 0) ->
|
Val when is_integer(Val) and (Val > 0) ->
|
||||||
@ -501,8 +506,8 @@ filter_fields([{SVar, [Val]} | Ds], Match, LServer)
|
|||||||
LVal = stringprep:tolower(Val),
|
LVal = stringprep:tolower(Val),
|
||||||
NewMatch = case SVar of
|
NewMatch = case SVar of
|
||||||
"user" ->
|
"user" ->
|
||||||
case gen_mod:get_module_opt(
|
case gen_mod:get_module_opt(LServer, ?MODULE,
|
||||||
?MODULE, search_all_hosts, true) of
|
search_all_hosts, true) of
|
||||||
true ->
|
true ->
|
||||||
Match#vcard_search{luser = make_val(LVal)};
|
Match#vcard_search{luser = make_val(LVal)};
|
||||||
false ->
|
false ->
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1, init/2, stop/0,
|
-export([start/2, init/2, stop/1,
|
||||||
process_local_iq/3,
|
process_local_iq/3,
|
||||||
process_sm_iq/3,
|
process_sm_iq/3,
|
||||||
remove_user/1]).
|
remove_user/1]).
|
||||||
@ -22,11 +22,11 @@
|
|||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
|
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_VCARD,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD,
|
||||||
?MODULE, process_local_iq, IQDisc),
|
?MODULE, process_local_iq, IQDisc),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_VCARD,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
|
||||||
?MODULE, process_sm_iq, IQDisc),
|
?MODULE, process_sm_iq, IQDisc),
|
||||||
LDAPServers = ejabberd_config:get_local_option(ldap_servers),
|
LDAPServers = ejabberd_config:get_local_option(ldap_servers),
|
||||||
RootDN = ejabberd_config:get_local_option(ldap_rootdn),
|
RootDN = ejabberd_config:get_local_option(ldap_rootdn),
|
||||||
@ -62,9 +62,9 @@ loop(Host) ->
|
|||||||
loop(Host)
|
loop(Host)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_VCARD),
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_VCARD),
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD),
|
||||||
ejabberd_mod_vcard_ldap ! stop,
|
ejabberd_mod_vcard_ldap ! stop,
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/1,
|
-export([start/2,
|
||||||
stop/0,
|
stop/1,
|
||||||
process_local_iq/3]).
|
process_local_iq/3]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
@ -21,13 +21,13 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
start(Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_VERSION,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VERSION,
|
||||||
?MODULE, process_local_iq, IQDisc).
|
?MODULE, process_local_iq, IQDisc).
|
||||||
|
|
||||||
stop() ->
|
stop(Host) ->
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_VERSION).
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VERSION).
|
||||||
|
|
||||||
|
|
||||||
process_local_iq(From, To, #iq{id = ID, type = Type,
|
process_local_iq(From, To, #iq{id = ID, type = Type,
|
||||||
|
@ -49,6 +49,34 @@ make_xhtml(Els) ->
|
|||||||
{"value", Value}])).
|
{"value", Value}])).
|
||||||
|
|
||||||
|
|
||||||
|
process_get({_, true},
|
||||||
|
#request{us = US,
|
||||||
|
path = ["admin", "server", SHost | RPath],
|
||||||
|
q = Query,
|
||||||
|
lang = Lang} = Request) ->
|
||||||
|
Host = jlib:nameprep(SHost),
|
||||||
|
case lists:member(Host, ?MYHOSTS) of
|
||||||
|
true ->
|
||||||
|
case US of
|
||||||
|
{User, Server} ->
|
||||||
|
case acl:match_rule(
|
||||||
|
Host, configure, jlib:make_jid(User, Server, "")) of
|
||||||
|
deny ->
|
||||||
|
{401, [], make_xhtml([?XC("h1", "Not Allowed")])};
|
||||||
|
allow ->
|
||||||
|
ejabberd_web_admin:process_admin(
|
||||||
|
Host, Request#request{path = RPath})
|
||||||
|
end;
|
||||||
|
undefined ->
|
||||||
|
{401,
|
||||||
|
[{"WWW-Authenticate", "basic realm=\"ejabberd\""}],
|
||||||
|
ejabberd_web:make_xhtml([{xmlelement, "h1", [],
|
||||||
|
[{xmlcdata, "401 Unauthorized"}]}])}
|
||||||
|
end;
|
||||||
|
false ->
|
||||||
|
{404, [], make_xhtml([?XC("h1", "Not found")])}
|
||||||
|
end;
|
||||||
|
|
||||||
process_get({_, true},
|
process_get({_, true},
|
||||||
#request{us = US,
|
#request{us = US,
|
||||||
path = ["admin" | RPath],
|
path = ["admin" | RPath],
|
||||||
@ -56,12 +84,13 @@ process_get({_, true},
|
|||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) ->
|
||||||
case US of
|
case US of
|
||||||
{User, Server} ->
|
{User, Server} ->
|
||||||
case acl:match_rule(configure, jlib:make_jid(User, Server, "")) of
|
case acl:match_rule(
|
||||||
|
global, configure, jlib:make_jid(User, Server, "")) of
|
||||||
deny ->
|
deny ->
|
||||||
{401, [], make_xhtml([?XC("h1", "Not Allowed")])};
|
{401, [], make_xhtml([?XC("h1", "Not Allowed")])};
|
||||||
allow ->
|
allow ->
|
||||||
ejabberd_web_admin:process_admin(
|
ejabberd_web_admin:process_admin(
|
||||||
Request#request{path = RPath})
|
global, Request#request{path = RPath})
|
||||||
end;
|
end;
|
||||||
undefined ->
|
undefined ->
|
||||||
{401,
|
{401,
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
-vsn('$Revision$ ').
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
%% External exports
|
%% External exports
|
||||||
-export([process_admin/1]).
|
-export([process_admin/2]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
@ -52,7 +52,7 @@
|
|||||||
{"size", Size}])).
|
{"size", Size}])).
|
||||||
-define(INPUTST(Type, Name, Value, Size), ?INPUT(Type, Name, ?T(Value), Size)).
|
-define(INPUTST(Type, Name, Value, Size), ?INPUT(Type, Name, ?T(Value), Size)).
|
||||||
|
|
||||||
make_xhtml(Els, Lang) ->
|
make_xhtml(Els, global, Lang) ->
|
||||||
{200, [html],
|
{200, [html],
|
||||||
{xmlelement, "html", [{"xmlns", "http://www.w3.org/1999/xhtml"},
|
{xmlelement, "html", [{"xmlns", "http://www.w3.org/1999/xhtml"},
|
||||||
{"xml:lang", Lang},
|
{"xml:lang", Lang},
|
||||||
@ -76,16 +76,60 @@ make_xhtml(Els, Lang) ->
|
|||||||
[?XE("ul",
|
[?XE("ul",
|
||||||
[?LI([?ACT("/admin/acls/", "Access Control Lists")]),
|
[?LI([?ACT("/admin/acls/", "Access Control Lists")]),
|
||||||
?LI([?ACT("/admin/access/", "Access Rules")]),
|
?LI([?ACT("/admin/access/", "Access Rules")]),
|
||||||
?LI([?ACT("/admin/users/", "Users")]),
|
|
||||||
?LI([?ACT("/admin/online-users/", "Online Users")]),
|
|
||||||
?LI([?ACT("/admin/last-activity/", "Last Activity")]),
|
|
||||||
?LI([?ACT("/admin/nodes/", "Nodes")]),
|
?LI([?ACT("/admin/nodes/", "Nodes")]),
|
||||||
?LI([?ACT("/admin/stats/", "Statistics")])
|
?LI([?ACT("/admin/stats/", "Statistics")])
|
||||||
|
]
|
||||||
|
)]),
|
||||||
|
?XAE("div",
|
||||||
|
[{"id", "content"}],
|
||||||
|
Els),
|
||||||
|
?XAE("div",
|
||||||
|
[{"id", "clearcopyright"}],
|
||||||
|
[{xmlcdata, ""}])]),
|
||||||
|
?XAE("div",
|
||||||
|
[{"id", "copyrightouter"}],
|
||||||
|
[?XAE("div",
|
||||||
|
[{"id", "copyright"}],
|
||||||
|
[?XCT("p",
|
||||||
|
"ejabberd (c) 2002-2005 Alexey Shchepin, 2004-2005 Process One")
|
||||||
|
])])])
|
||||||
|
]}};
|
||||||
|
|
||||||
|
make_xhtml(Els, Host, Lang) ->
|
||||||
|
Base = "/admin/server/" ++ Host ++ "/",
|
||||||
|
{200, [html],
|
||||||
|
{xmlelement, "html", [{"xmlns", "http://www.w3.org/1999/xhtml"},
|
||||||
|
{"xml:lang", Lang},
|
||||||
|
{"lang", Lang}],
|
||||||
|
[{xmlelement, "head", [],
|
||||||
|
[{xmlelement, "meta", [{"http-equiv", "Content-Type"},
|
||||||
|
{"content", "text/html; charset=utf-8"}], []},
|
||||||
|
{xmlelement, "link", [{"href", Base ++ "style.css"},
|
||||||
|
{"type", "text/css"},
|
||||||
|
{"rel", "stylesheet"}], []}]},
|
||||||
|
?XE("body",
|
||||||
|
[?XAE("div",
|
||||||
|
[{"id", "container"}],
|
||||||
|
[?XAE("div",
|
||||||
|
[{"id", "header"}],
|
||||||
|
[?XE("h1",
|
||||||
|
[?ACT(Base, "ejabberd administration")]
|
||||||
|
)]),
|
||||||
|
?XAE("div",
|
||||||
|
[{"id", "navigation"}],
|
||||||
|
[?XE("ul",
|
||||||
|
[?LI([?ACT(Base ++ "acls/", "Access Control Lists")]),
|
||||||
|
?LI([?ACT(Base ++ "access/", "Access Rules")]),
|
||||||
|
?LI([?ACT(Base ++ "users/", "Users")]),
|
||||||
|
?LI([?ACT(Base ++ "online-users/", "Online Users")]),
|
||||||
|
?LI([?ACT(Base ++ "last-activity/", "Last Activity")]),
|
||||||
|
?LI([?ACT(Base ++ "nodes/", "Nodes")]),
|
||||||
|
?LI([?ACT(Base ++ "stats/", "Statistics")])
|
||||||
] ++
|
] ++
|
||||||
case lists:member(mod_shared_roster,
|
case lists:member(mod_shared_roster,
|
||||||
gen_mod:loaded_modules()) of
|
gen_mod:loaded_modules(Host)) of
|
||||||
true ->
|
true ->
|
||||||
[?LI([?ACT("/admin/shared-roster/", "Shared Roster")])];
|
[?LI([?ACT(Base ++ "shared-roster/", "Shared Roster")])];
|
||||||
false ->
|
false ->
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
@ -105,7 +149,14 @@ make_xhtml(Els, Lang) ->
|
|||||||
])])])
|
])])])
|
||||||
]}}.
|
]}}.
|
||||||
|
|
||||||
css() -> "
|
css(Host) ->
|
||||||
|
Base = case Host of
|
||||||
|
global ->
|
||||||
|
"/admin/";
|
||||||
|
_ ->
|
||||||
|
"/admin/server/" ++ Host ++ "/"
|
||||||
|
end,
|
||||||
|
"
|
||||||
html,body {
|
html,body {
|
||||||
background: white;
|
background: white;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -130,7 +181,7 @@ html>body #container {
|
|||||||
height: 55px;
|
height: 55px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background: transparent url(\"/admin/logo-fill.png\");
|
background: transparent url(\"" ++ Base ++ "logo-fill.png\");
|
||||||
}
|
}
|
||||||
|
|
||||||
#header h1 a {
|
#header h1 a {
|
||||||
@ -141,7 +192,7 @@ html>body #container {
|
|||||||
height: 55px;
|
height: 55px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background: transparent url(\"/admin/logo.png\") no-repeat;
|
background: transparent url(\"" ++ Base ++ "logo.png\") no-repeat;
|
||||||
display: block;
|
display: block;
|
||||||
text-indent: -700em;
|
text-indent: -700em;
|
||||||
}
|
}
|
||||||
@ -466,7 +517,8 @@ logo_fill() ->
|
|||||||
"1c5dvhSU2BpKqBXl6R0ljYGS50R5zVC+tVD+vfE6YyUexE9x7g4AAAAASUVO"
|
"1c5dvhSU2BpKqBXl6R0ljYGS50R5zVC+tVD+vfE6YyUexE9x7g4AAAAASUVO"
|
||||||
"RK5CYII=").
|
"RK5CYII=").
|
||||||
|
|
||||||
process_admin(#request{us = US,
|
process_admin(global,
|
||||||
|
#request{us = US,
|
||||||
path = [],
|
path = [],
|
||||||
q = Query,
|
q = Query,
|
||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) ->
|
||||||
@ -476,41 +528,63 @@ process_admin(#request{us = US,
|
|||||||
?ACT("/admin/acls-raw/", "(raw)")]),
|
?ACT("/admin/acls-raw/", "(raw)")]),
|
||||||
?LI([?ACT("/admin/access/", "Access Rules"), ?C(" "),
|
?LI([?ACT("/admin/access/", "Access Rules"), ?C(" "),
|
||||||
?ACT("/admin/access-raw/", "(raw)")]),
|
?ACT("/admin/access-raw/", "(raw)")]),
|
||||||
?LI([?ACT("/admin/users/", "Users")]),
|
|
||||||
?LI([?ACT("/admin/online-users/", "Online Users")]),
|
|
||||||
?LI([?ACT("/admin/last-activity/", "Last Activity")]),
|
|
||||||
?LI([?ACT("/admin/nodes/", "Nodes")]),
|
?LI([?ACT("/admin/nodes/", "Nodes")]),
|
||||||
?LI([?ACT("/admin/stats/", "Statistics")])
|
?LI([?ACT("/admin/stats/", "Statistics")])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
], global, Lang);
|
||||||
|
|
||||||
|
process_admin(Host,
|
||||||
|
#request{us = US,
|
||||||
|
path = [],
|
||||||
|
q = Query,
|
||||||
|
lang = Lang} = Request) ->
|
||||||
|
Base = "/admin/server/" ++ Host ++ "/",
|
||||||
|
make_xhtml([?XCT("h1", "ejabberd administration"),
|
||||||
|
?XE("ul",
|
||||||
|
[?LI([?ACT(Base ++ "acls/", "Access Control Lists"), ?C(" "),
|
||||||
|
?ACT(Base ++ "acls-raw/", "(raw)")]),
|
||||||
|
?LI([?ACT(Base ++ "access/", "Access Rules"), ?C(" "),
|
||||||
|
?ACT(Base ++ "access-raw/", "(raw)")]),
|
||||||
|
?LI([?ACT(Base ++ "users/", "Users")]),
|
||||||
|
?LI([?ACT(Base ++ "online-users/", "Online Users")]),
|
||||||
|
?LI([?ACT(Base ++ "last-activity/", "Last Activity")]),
|
||||||
|
?LI([?ACT(Base ++ "nodes/", "Nodes")]),
|
||||||
|
?LI([?ACT(Base ++ "stats/", "Statistics")])
|
||||||
] ++
|
] ++
|
||||||
case lists:member(mod_shared_roster,
|
case lists:member(mod_shared_roster,
|
||||||
gen_mod:loaded_modules()) of
|
gen_mod:loaded_modules(Host)) of
|
||||||
true ->
|
true ->
|
||||||
[?LI([?ACT("/admin/shared-roster/", "Shared Roster")])];
|
[?LI([?ACT(Base ++ "shared-roster/", "Shared Roster")])];
|
||||||
false ->
|
false ->
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
], Lang);
|
], Host, Lang);
|
||||||
|
|
||||||
process_admin(#request{us = US,
|
process_admin(Host,
|
||||||
|
#request{us = US,
|
||||||
path = ["style.css"],
|
path = ["style.css"],
|
||||||
q = Query,
|
q = Query,
|
||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) ->
|
||||||
{200, [{"Content-Type", "text/css"}], css()};
|
{200, [{"Content-Type", "text/css"}], css(Host)};
|
||||||
|
|
||||||
process_admin(#request{us = US,
|
process_admin(Host,
|
||||||
|
#request{us = US,
|
||||||
path = ["logo.png"],
|
path = ["logo.png"],
|
||||||
q = Query,
|
q = Query,
|
||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) ->
|
||||||
{200, [{"Content-Type", "image/png"}], logo()};
|
{200, [{"Content-Type", "image/png"}], logo()};
|
||||||
|
|
||||||
process_admin(#request{us = US,
|
process_admin(Host,
|
||||||
|
#request{us = US,
|
||||||
path = ["logo-fill.png"],
|
path = ["logo-fill.png"],
|
||||||
q = Query,
|
q = Query,
|
||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) ->
|
||||||
{200, [{"Content-Type", "image/png"}], logo_fill()};
|
{200, [{"Content-Type", "image/png"}], logo_fill()};
|
||||||
|
|
||||||
process_admin(#request{us = US,
|
process_admin(Host,
|
||||||
|
#request{us = US,
|
||||||
path = ["acls-raw"],
|
path = ["acls-raw"],
|
||||||
q = Query,
|
q = Query,
|
||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) ->
|
||||||
@ -520,7 +594,7 @@ process_admin(#request{us = US,
|
|||||||
{ok, Tokens, _} ->
|
{ok, Tokens, _} ->
|
||||||
case erl_parse:parse_term(Tokens) of
|
case erl_parse:parse_term(Tokens) of
|
||||||
{ok, NewACLs} ->
|
{ok, NewACLs} ->
|
||||||
case acl:add_list(NewACLs, true) of
|
case acl:add_list(Host, NewACLs, true) of
|
||||||
ok ->
|
ok ->
|
||||||
ok;
|
ok;
|
||||||
_ ->
|
_ ->
|
||||||
@ -535,7 +609,11 @@ process_admin(#request{us = US,
|
|||||||
_ ->
|
_ ->
|
||||||
nothing
|
nothing
|
||||||
end,
|
end,
|
||||||
ACLs = lists:flatten(io_lib:format("~p.", [ets:tab2list(acl)])),
|
ACLs = lists:flatten(
|
||||||
|
io_lib:format(
|
||||||
|
"~p.", [lists:keysort(
|
||||||
|
2, ets:select(acl, [{{acl, {'$1', Host}, '$2'},
|
||||||
|
[], [{{acl, '$1', '$2'}}]}]))])),
|
||||||
make_xhtml([?XCT("h1", "ejabberd access control lists configuration")] ++
|
make_xhtml([?XCT("h1", "ejabberd access control lists configuration")] ++
|
||||||
case Res of
|
case Res of
|
||||||
ok -> [?CT("submitted"), ?P];
|
ok -> [?CT("submitted"), ?P];
|
||||||
@ -550,9 +628,10 @@ process_admin(#request{us = US,
|
|||||||
?BR,
|
?BR,
|
||||||
?INPUTT("submit", "submit", "Submit")
|
?INPUTT("submit", "submit", "Submit")
|
||||||
])
|
])
|
||||||
], Lang);
|
], Host, Lang);
|
||||||
|
|
||||||
process_admin(#request{method = Method,
|
process_admin(Host,
|
||||||
|
#request{method = Method,
|
||||||
us = US,
|
us = US,
|
||||||
path = ["acls"],
|
path = ["acls"],
|
||||||
q = Query,
|
q = Query,
|
||||||
@ -560,12 +639,12 @@ process_admin(#request{method = Method,
|
|||||||
?INFO_MSG("query: ~p", [Query]),
|
?INFO_MSG("query: ~p", [Query]),
|
||||||
Res = case Method of
|
Res = case Method of
|
||||||
'POST' ->
|
'POST' ->
|
||||||
case catch acl_parse_query(Query) of
|
case catch acl_parse_query(Host, Query) of
|
||||||
{'EXIT', _} ->
|
{'EXIT', _} ->
|
||||||
error;
|
error;
|
||||||
NewACLs ->
|
NewACLs ->
|
||||||
?INFO_MSG("NewACLs: ~p", [NewACLs]),
|
?INFO_MSG("NewACLs at ~s: ~p", [Host, NewACLs]),
|
||||||
case acl:add_list(NewACLs, true) of
|
case acl:add_list(Host, NewACLs, true) of
|
||||||
ok ->
|
ok ->
|
||||||
?INFO_MSG("NewACLs: ok", []),
|
?INFO_MSG("NewACLs: ok", []),
|
||||||
ok;
|
ok;
|
||||||
@ -576,7 +655,9 @@ process_admin(#request{method = Method,
|
|||||||
_ ->
|
_ ->
|
||||||
nothing
|
nothing
|
||||||
end,
|
end,
|
||||||
ACLs = lists:keysort(2, ets:tab2list(acl)),
|
ACLs = lists:keysort(
|
||||||
|
2, ets:select(acl, [{{acl, {'$1', Host}, '$2'},
|
||||||
|
[], [{{acl, '$1', '$2'}}]}])),
|
||||||
make_xhtml([?XCT("h1", "ejabberd access control lists configuration")] ++
|
make_xhtml([?XCT("h1", "ejabberd access control lists configuration")] ++
|
||||||
case Res of
|
case Res of
|
||||||
ok -> [?CT("submitted"), ?P];
|
ok -> [?CT("submitted"), ?P];
|
||||||
@ -591,9 +672,10 @@ process_admin(#request{method = Method,
|
|||||||
?C(" "),
|
?C(" "),
|
||||||
?INPUTT("submit", "submit", "Submit")
|
?INPUTT("submit", "submit", "Submit")
|
||||||
])
|
])
|
||||||
], Lang);
|
], Host, Lang);
|
||||||
|
|
||||||
process_admin(#request{us = US,
|
process_admin(Host,
|
||||||
|
#request{us = US,
|
||||||
path = ["access-raw"],
|
path = ["access-raw"],
|
||||||
q = Query,
|
q = Query,
|
||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) ->
|
||||||
@ -601,8 +683,9 @@ process_admin(#request{us = US,
|
|||||||
fun(Rs) ->
|
fun(Rs) ->
|
||||||
mnesia:transaction(
|
mnesia:transaction(
|
||||||
fun() ->
|
fun() ->
|
||||||
Os = mnesia:select(config,
|
Os = mnesia:select(
|
||||||
[{{config, {access, '$1'}, '$2'},
|
config,
|
||||||
|
[{{config, {access, '$1', Host}, '$2'},
|
||||||
[],
|
[],
|
||||||
['$_']}]),
|
['$_']}]),
|
||||||
lists:foreach(fun(O) ->
|
lists:foreach(fun(O) ->
|
||||||
@ -611,7 +694,7 @@ process_admin(#request{us = US,
|
|||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({access, Name, Rules}) ->
|
fun({access, Name, Rules}) ->
|
||||||
mnesia:write({config,
|
mnesia:write({config,
|
||||||
{access, Name},
|
{access, Name, Host},
|
||||||
Rules})
|
Rules})
|
||||||
end, Rs)
|
end, Rs)
|
||||||
end)
|
end)
|
||||||
@ -641,7 +724,7 @@ process_admin(#request{us = US,
|
|||||||
lists:flatten(
|
lists:flatten(
|
||||||
io_lib:format(
|
io_lib:format(
|
||||||
"~p.", [ets:select(config,
|
"~p.", [ets:select(config,
|
||||||
[{{config, {access, '$1'}, '$2'},
|
[{{config, {access, '$1', Host}, '$2'},
|
||||||
[],
|
[],
|
||||||
[{{access, '$1', '$2'}}]}])])),
|
[{{access, '$1', '$2'}}]}])])),
|
||||||
make_xhtml([?XCT("h1", "ejabberd access rules configuration")] ++
|
make_xhtml([?XCT("h1", "ejabberd access rules configuration")] ++
|
||||||
@ -658,9 +741,10 @@ process_admin(#request{us = US,
|
|||||||
?BR,
|
?BR,
|
||||||
?INPUTT("submit", "submit", "Submit")
|
?INPUTT("submit", "submit", "Submit")
|
||||||
])
|
])
|
||||||
], Lang);
|
], Host, Lang);
|
||||||
|
|
||||||
process_admin(#request{method = Method,
|
process_admin(Host,
|
||||||
|
#request{method = Method,
|
||||||
us = US,
|
us = US,
|
||||||
path = ["access"],
|
path = ["access"],
|
||||||
q = Query,
|
q = Query,
|
||||||
@ -668,7 +752,7 @@ process_admin(#request{method = Method,
|
|||||||
?INFO_MSG("query: ~p", [Query]),
|
?INFO_MSG("query: ~p", [Query]),
|
||||||
Res = case Method of
|
Res = case Method of
|
||||||
'POST' ->
|
'POST' ->
|
||||||
case catch access_parse_query(Query) of
|
case catch access_parse_query(Host, Query) of
|
||||||
{'EXIT', _} ->
|
{'EXIT', _} ->
|
||||||
error;
|
error;
|
||||||
ok ->
|
ok ->
|
||||||
@ -679,7 +763,7 @@ process_admin(#request{method = Method,
|
|||||||
end,
|
end,
|
||||||
AccessRules =
|
AccessRules =
|
||||||
ets:select(config,
|
ets:select(config,
|
||||||
[{{config, {access, '$1'}, '$2'},
|
[{{config, {access, '$1', Host}, '$2'},
|
||||||
[],
|
[],
|
||||||
[{{access, '$1', '$2'}}]}]),
|
[{{access, '$1', '$2'}}]}]),
|
||||||
make_xhtml([?XCT("h1", "ejabberd access rules configuration")] ++
|
make_xhtml([?XCT("h1", "ejabberd access rules configuration")] ++
|
||||||
@ -694,9 +778,10 @@ process_admin(#request{method = Method,
|
|||||||
?BR,
|
?BR,
|
||||||
?INPUTT("submit", "delete", "Delete Selected")
|
?INPUTT("submit", "delete", "Delete Selected")
|
||||||
])
|
])
|
||||||
], Lang);
|
], Host, Lang);
|
||||||
|
|
||||||
process_admin(#request{method = Method,
|
process_admin(Host,
|
||||||
|
#request{method = Method,
|
||||||
us = US,
|
us = US,
|
||||||
path = ["access", SName],
|
path = ["access", SName],
|
||||||
q = Query,
|
q = Query,
|
||||||
@ -708,7 +793,7 @@ process_admin(#request{method = Method,
|
|||||||
case parse_access_rule(String) of
|
case parse_access_rule(String) of
|
||||||
{ok, Rs} ->
|
{ok, Rs} ->
|
||||||
ejabberd_config:add_global_option(
|
ejabberd_config:add_global_option(
|
||||||
{access, Name}, Rs),
|
{access, Name, Host}, Rs),
|
||||||
ok;
|
ok;
|
||||||
_ ->
|
_ ->
|
||||||
error
|
error
|
||||||
@ -716,7 +801,7 @@ process_admin(#request{method = Method,
|
|||||||
_ ->
|
_ ->
|
||||||
nothing
|
nothing
|
||||||
end,
|
end,
|
||||||
Rules = case ejabberd_config:get_global_option({access, Name}) of
|
Rules = case ejabberd_config:get_global_option({access, Name, Host}) of
|
||||||
undefined ->
|
undefined ->
|
||||||
[];
|
[];
|
||||||
Rs1 ->
|
Rs1 ->
|
||||||
@ -734,34 +819,38 @@ process_admin(#request{method = Method,
|
|||||||
?BR,
|
?BR,
|
||||||
?INPUTT("submit", "submit", "Submit")
|
?INPUTT("submit", "submit", "Submit")
|
||||||
])
|
])
|
||||||
], Lang);
|
], Host, Lang);
|
||||||
|
|
||||||
process_admin(#request{us = US,
|
process_admin(Host,
|
||||||
|
#request{us = US,
|
||||||
path = ["users"],
|
path = ["users"],
|
||||||
q = Query,
|
q = Query,
|
||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) when is_list(Host) ->
|
||||||
Res = list_users(Query, Lang),
|
Res = list_users(Host, Query, Lang),
|
||||||
make_xhtml([?XCT("h1", "ejabberd users")] ++ Res, Lang);
|
make_xhtml([?XCT("h1", "ejabberd users")] ++ Res, Host, Lang);
|
||||||
|
|
||||||
process_admin(#request{us = US,
|
process_admin(Host,
|
||||||
|
#request{us = US,
|
||||||
path = ["users", Diap],
|
path = ["users", Diap],
|
||||||
q = Query,
|
q = Query,
|
||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) when is_list(Host) ->
|
||||||
Res = list_users_in_diapason(Diap, Lang),
|
Res = list_users_in_diapason(Host, Diap, Lang),
|
||||||
make_xhtml([?XCT("h1", "ejabberd users")] ++ Res, Lang);
|
make_xhtml([?XCT("h1", "ejabberd users")] ++ Res, Host, Lang);
|
||||||
|
|
||||||
process_admin(#request{us = US,
|
process_admin(Host,
|
||||||
|
#request{us = US,
|
||||||
path = ["online-users"],
|
path = ["online-users"],
|
||||||
q = Query,
|
q = Query,
|
||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) when is_list(Host) ->
|
||||||
Res = list_online_users(Lang),
|
Res = list_online_users(Host, Lang),
|
||||||
make_xhtml([?XCT("h1", "ejabberd users")] ++ Res, Lang);
|
make_xhtml([?XCT("h1", "ejabberd users")] ++ Res, Host, Lang);
|
||||||
|
|
||||||
process_admin(#request{method = Method,
|
process_admin(Host,
|
||||||
|
#request{method = Method,
|
||||||
us = US,
|
us = US,
|
||||||
path = ["last-activity"],
|
path = ["last-activity"],
|
||||||
q = Query,
|
q = Query,
|
||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) when is_list(Host) ->
|
||||||
?INFO_MSG("query: ~p", [Query]),
|
?INFO_MSG("query: ~p", [Query]),
|
||||||
Month = case lists:keysearch("period", 1, Query) of
|
Month = case lists:keysearch("period", 1, Query) of
|
||||||
{value, {_, Val}} ->
|
{value, {_, Val}} ->
|
||||||
@ -771,9 +860,9 @@ process_admin(#request{method = Method,
|
|||||||
end,
|
end,
|
||||||
Res = case lists:keysearch("ordinary", 1, Query) of
|
Res = case lists:keysearch("ordinary", 1, Query) of
|
||||||
{value, {_, _}} ->
|
{value, {_, _}} ->
|
||||||
list_last_activity(Lang, false, Month);
|
list_last_activity(Host, Lang, false, Month);
|
||||||
_ ->
|
_ ->
|
||||||
list_last_activity(Lang, true, Month)
|
list_last_activity(Host, Lang, true, Month)
|
||||||
end,
|
end,
|
||||||
make_xhtml([?XCT("h1", "Users last activity")] ++
|
make_xhtml([?XCT("h1", "Users last activity")] ++
|
||||||
[?XAE("form", [{"method", "post"}],
|
[?XAE("form", [{"method", "post"}],
|
||||||
@ -795,71 +884,80 @@ process_admin(#request{method = Method,
|
|||||||
?C(" "),
|
?C(" "),
|
||||||
?INPUTT("submit", "integral", "Show Integral Table")
|
?INPUTT("submit", "integral", "Show Integral Table")
|
||||||
])] ++
|
])] ++
|
||||||
Res, Lang);
|
Res, Host, Lang);
|
||||||
|
|
||||||
process_admin(#request{us = US,
|
process_admin(Host,
|
||||||
|
#request{us = US,
|
||||||
path = ["stats"],
|
path = ["stats"],
|
||||||
q = Query,
|
q = Query,
|
||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) ->
|
||||||
Res = get_stats(Lang),
|
Res = get_stats(Host, Lang),
|
||||||
make_xhtml([?XCT("h1", "ejabberd stats")] ++ Res, Lang);
|
make_xhtml([?XCT("h1", "ejabberd stats")] ++ Res, Host, Lang);
|
||||||
|
|
||||||
process_admin(#request{us = US,
|
process_admin(Host,
|
||||||
|
#request{us = US,
|
||||||
path = ["user", U],
|
path = ["user", U],
|
||||||
q = Query,
|
q = Query,
|
||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) ->
|
||||||
Res = user_info(U, Query, Lang),
|
Res = user_info(U, Host, Query, Lang),
|
||||||
make_xhtml(Res, Lang);
|
make_xhtml(Res, Host, Lang);
|
||||||
|
|
||||||
process_admin(#request{us = US,
|
process_admin(Host,
|
||||||
|
#request{us = US,
|
||||||
path = ["user", U, "queue"],
|
path = ["user", U, "queue"],
|
||||||
q = Query,
|
q = Query,
|
||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) ->
|
||||||
Res = user_queue(U, Query, Lang),
|
Res = user_queue(U, Host, Query, Lang),
|
||||||
make_xhtml(Res, Lang);
|
make_xhtml(Res, Host, Lang);
|
||||||
|
|
||||||
process_admin(#request{us = US,
|
process_admin(Host,
|
||||||
|
#request{us = US,
|
||||||
path = ["user", U, "roster"],
|
path = ["user", U, "roster"],
|
||||||
q = Query,
|
q = Query,
|
||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) ->
|
||||||
Res = user_roster(U, Query, Lang, true),
|
Res = user_roster(U, Host, Query, Lang, true),
|
||||||
make_xhtml(Res, Lang);
|
make_xhtml(Res, Host, Lang);
|
||||||
|
|
||||||
process_admin(#request{us = US,
|
process_admin(Host,
|
||||||
|
#request{us = US,
|
||||||
path = ["nodes"],
|
path = ["nodes"],
|
||||||
q = Query,
|
q = Query,
|
||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) ->
|
||||||
Res = get_nodes(Lang),
|
Res = get_nodes(Lang),
|
||||||
make_xhtml(Res, Lang);
|
make_xhtml(Res, Host, Lang);
|
||||||
|
|
||||||
process_admin(#request{us = US,
|
process_admin(Host,
|
||||||
|
#request{us = US,
|
||||||
path = ["node", SNode | NPath],
|
path = ["node", SNode | NPath],
|
||||||
q = Query,
|
q = Query,
|
||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) ->
|
||||||
case search_running_node(SNode) of
|
case search_running_node(SNode) of
|
||||||
false ->
|
false ->
|
||||||
make_xhtml([?XCT("h1", "Node not found")], Lang);
|
make_xhtml([?XCT("h1", "Node not found")], Host, Lang);
|
||||||
Node ->
|
Node ->
|
||||||
Res = get_node(Node, NPath, Query, Lang),
|
Res = get_node(Host, Node, NPath, Query, Lang),
|
||||||
make_xhtml(Res, Lang)
|
make_xhtml(Res, Host, Lang)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
process_admin(#request{us = US,
|
process_admin(Host,
|
||||||
|
#request{us = US,
|
||||||
path = ["shared-roster"],
|
path = ["shared-roster"],
|
||||||
q = Query,
|
q = Query,
|
||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) ->
|
||||||
Res = list_shared_roster_groups(Query, Lang),
|
Res = list_shared_roster_groups(Query, Lang),
|
||||||
make_xhtml(Res, Lang);
|
make_xhtml(Res, Host, Lang);
|
||||||
|
|
||||||
process_admin(#request{us = US,
|
process_admin(Host,
|
||||||
|
#request{us = US,
|
||||||
path = ["shared-roster", Group],
|
path = ["shared-roster", Group],
|
||||||
q = Query,
|
q = Query,
|
||||||
lang = Lang} = Request) ->
|
lang = Lang} = Request) ->
|
||||||
Res = shared_roster_group(Group, Query, Lang),
|
Res = shared_roster_group(Group, Query, Lang),
|
||||||
make_xhtml(Res, Lang);
|
make_xhtml(Res, Host, Lang);
|
||||||
|
|
||||||
process_admin(#request{lang = Lang}) ->
|
process_admin(Host,
|
||||||
setelement(1, make_xhtml([?XC("h1", "Not found")], Lang), 404).
|
#request{lang = Lang}) ->
|
||||||
|
setelement(1, make_xhtml([?XC("h1", "Not found")], Host, Lang), 404).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -924,8 +1022,9 @@ term_to_id(T) ->
|
|||||||
jlib:encode_base64(binary_to_list(term_to_binary(T))).
|
jlib:encode_base64(binary_to_list(term_to_binary(T))).
|
||||||
|
|
||||||
|
|
||||||
acl_parse_query(Query) ->
|
acl_parse_query(Host, Query) ->
|
||||||
ACLs = ets:tab2list(acl),
|
ACLs = ets:select(acl, [{{acl, {'$1', Host}, '$2'},
|
||||||
|
[], [{{acl, '$1', '$2'}}]}]),
|
||||||
case lists:keysearch("submit", 1, Query) of
|
case lists:keysearch("submit", 1, Query) of
|
||||||
{value, _} ->
|
{value, _} ->
|
||||||
acl_parse_submit(ACLs, Query);
|
acl_parse_submit(ACLs, Query);
|
||||||
@ -977,7 +1076,7 @@ string_to_spec("server", Val) ->
|
|||||||
{server, Val};
|
{server, Val};
|
||||||
string_to_spec("user_server", Val) ->
|
string_to_spec("user_server", Val) ->
|
||||||
#jid{luser = U, lserver = S, resource = ""} = jlib:string_to_jid(Val),
|
#jid{luser = U, lserver = S, resource = ""} = jlib:string_to_jid(Val),
|
||||||
{user_server, U, S};
|
{user, U, S};
|
||||||
string_to_spec("raw", Val) ->
|
string_to_spec("raw", Val) ->
|
||||||
{ok, Tokens, _} = erl_scan:string(Val ++ "."),
|
{ok, Tokens, _} = erl_scan:string(Val ++ "."),
|
||||||
{ok, NewSpec} = erl_parse:parse_term(Tokens),
|
{ok, NewSpec} = erl_parse:parse_term(Tokens),
|
||||||
@ -1016,31 +1115,31 @@ access_rules_to_xhtml(AccessRules, Lang) ->
|
|||||||
)]
|
)]
|
||||||
)]).
|
)]).
|
||||||
|
|
||||||
access_parse_query(Query) ->
|
access_parse_query(Host, Query) ->
|
||||||
AccessRules =
|
AccessRules =
|
||||||
ets:select(config,
|
ets:select(config,
|
||||||
[{{config, {access, '$1'}, '$2'},
|
[{{config, {access, '$1', Host}, '$2'},
|
||||||
[],
|
[],
|
||||||
[{{access, '$1', '$2'}}]}]),
|
[{{access, '$1', '$2'}}]}]),
|
||||||
case lists:keysearch("addnew", 1, Query) of
|
case lists:keysearch("addnew", 1, Query) of
|
||||||
{value, _} ->
|
{value, _} ->
|
||||||
access_parse_addnew(AccessRules, Query);
|
access_parse_addnew(AccessRules, Host, Query);
|
||||||
_ ->
|
_ ->
|
||||||
case lists:keysearch("delete", 1, Query) of
|
case lists:keysearch("delete", 1, Query) of
|
||||||
{value, _} ->
|
{value, _} ->
|
||||||
access_parse_delete(AccessRules, Query)
|
access_parse_delete(AccessRules, Host, Query)
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
access_parse_addnew(AccessRules, Query) ->
|
access_parse_addnew(AccessRules, Host, Query) ->
|
||||||
case lists:keysearch("namenew", 1, Query) of
|
case lists:keysearch("namenew", 1, Query) of
|
||||||
{value, {_, String}} when String /= "" ->
|
{value, {_, String}} when String /= "" ->
|
||||||
Name = list_to_atom(String),
|
Name = list_to_atom(String),
|
||||||
ejabberd_config:add_global_option({access, Name}, []),
|
ejabberd_config:add_global_option({access, Name, Host}, []),
|
||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
access_parse_delete(AccessRules, Query) ->
|
access_parse_delete(AccessRules, Host, Query) ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({access, Name, _Rules} = AccessRule) ->
|
fun({access, Name, _Rules} = AccessRule) ->
|
||||||
ID = term_to_id(AccessRule),
|
ID = term_to_id(AccessRule),
|
||||||
@ -1048,7 +1147,7 @@ access_parse_delete(AccessRules, Query) ->
|
|||||||
true ->
|
true ->
|
||||||
mnesia:transaction(
|
mnesia:transaction(
|
||||||
fun() ->
|
fun() ->
|
||||||
mnesia:delete({config, {access, Name}})
|
mnesia:delete({config, {access, Name, Host}})
|
||||||
end);
|
end);
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
@ -1091,9 +1190,9 @@ parse_access_rule(Text) ->
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
list_users(Query, Lang) ->
|
list_users(Host, Query, Lang) ->
|
||||||
Res = list_users_parse_query(Query),
|
Res = list_users_parse_query(Query),
|
||||||
Users = ejabberd_auth:dirty_get_registered_users(),
|
Users = ejabberd_auth:get_vh_registered_users(Host),
|
||||||
SUsers = lists:sort([{S, U} || {U, S} <- Users]),
|
SUsers = lists:sort([{S, U} || {U, S} <- Users]),
|
||||||
FUsers =
|
FUsers =
|
||||||
case length(SUsers) of
|
case length(SUsers) of
|
||||||
@ -1162,8 +1261,8 @@ list_users_parse_query(Query) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
list_users_in_diapason(Diap, Lang) ->
|
list_users_in_diapason(Host, Diap, Lang) ->
|
||||||
Users = ejabberd_auth:dirty_get_registered_users(),
|
Users = ejabberd_auth:get_vh_registered_users(Host),
|
||||||
SUsers = lists:sort([{S, U} || {U, S} <- Users]),
|
SUsers = lists:sort([{S, U} || {U, S} <- Users]),
|
||||||
{ok, [S1, S2]} = regexp:split(Diap, "-"),
|
{ok, [S1, S2]} = regexp:split(Diap, "-"),
|
||||||
N1 = list_to_integer(S1),
|
N1 = list_to_integer(S1),
|
||||||
@ -1184,7 +1283,7 @@ list_given_users(Users, Prefix, Lang) ->
|
|||||||
US = {User, Server},
|
US = {User, Server},
|
||||||
QueueLen = length(mnesia:dirty_read({offline_msg, US})),
|
QueueLen = length(mnesia:dirty_read({offline_msg, US})),
|
||||||
FQueueLen = [?AC(Prefix ++ "user/" ++
|
FQueueLen = [?AC(Prefix ++ "user/" ++
|
||||||
User ++ "@" ++ Server ++ "/queue/",
|
User ++ "/queue/",
|
||||||
integer_to_list(QueueLen))],
|
integer_to_list(QueueLen))],
|
||||||
FLast =
|
FLast =
|
||||||
case ejabberd_sm:get_user_resources(User, Server) of
|
case ejabberd_sm:get_user_resources(User, Server) of
|
||||||
@ -1208,8 +1307,7 @@ list_given_users(Users, Prefix, Lang) ->
|
|||||||
?T("Online")
|
?T("Online")
|
||||||
end,
|
end,
|
||||||
?XE("tr",
|
?XE("tr",
|
||||||
[?XE("td", [?AC(Prefix ++ "user/" ++
|
[?XE("td", [?AC(Prefix ++ "user/" ++ User ++ "/",
|
||||||
us_to_list(US) ++ "/",
|
|
||||||
us_to_list(US))]),
|
us_to_list(US))]),
|
||||||
?XE("td", FQueueLen),
|
?XE("td", FQueueLen),
|
||||||
?XC("td", FLast)])
|
?XC("td", FLast)])
|
||||||
@ -1223,14 +1321,13 @@ su_to_list({Server, User}) ->
|
|||||||
jlib:jid_to_string({User, Server, ""}).
|
jlib:jid_to_string({User, Server, ""}).
|
||||||
|
|
||||||
|
|
||||||
get_stats(Lang) ->
|
get_stats(global, Lang) ->
|
||||||
OnlineUsers = mnesia:table_info(presence, size),
|
OnlineUsers = mnesia:table_info(presence, size),
|
||||||
AuthUsers = mnesia:table_info(session, size),
|
AuthUsers = mnesia:table_info(session, size),
|
||||||
RegisteredUsers = mnesia:table_info(passwd, size),
|
RegisteredUsers = mnesia:table_info(passwd, size),
|
||||||
S2SConns = ejabberd_s2s:dirty_get_connections(),
|
S2SConns = ejabberd_s2s:dirty_get_connections(),
|
||||||
S2SConnections = length(S2SConns),
|
S2SConnections = length(S2SConns),
|
||||||
S2SServers = length(lists:usort([element(2, C) || C <- S2SConns])),
|
S2SServers = length(lists:usort([element(2, C) || C <- S2SConns])),
|
||||||
|
|
||||||
[?XAE("table", [],
|
[?XAE("table", [],
|
||||||
[?XE("tbody",
|
[?XE("tbody",
|
||||||
[?XE("tr", [?XCT("td", "Registered users"),
|
[?XE("tr", [?XCT("td", "Registered users"),
|
||||||
@ -1244,22 +1341,31 @@ get_stats(Lang) ->
|
|||||||
?XE("tr", [?XCT("td", "Outgoing S2S servers"),
|
?XE("tr", [?XCT("td", "Outgoing S2S servers"),
|
||||||
?XC("td", integer_to_list(S2SServers))])
|
?XC("td", integer_to_list(S2SServers))])
|
||||||
])
|
])
|
||||||
|
])];
|
||||||
|
|
||||||
|
get_stats(Host, Lang) ->
|
||||||
|
OnlineUsers = length(ejabberd_sm:get_vh_session_list(Host)),
|
||||||
|
RegisteredUsers = length(ejabberd_auth:get_vh_registered_users(Host)),
|
||||||
|
[?XAE("table", [],
|
||||||
|
[?XE("tbody",
|
||||||
|
[?XE("tr", [?XCT("td", "Registered users"),
|
||||||
|
?XC("td", integer_to_list(RegisteredUsers))]),
|
||||||
|
?XE("tr", [?XCT("td", "Online users"),
|
||||||
|
?XC("td", integer_to_list(OnlineUsers))])
|
||||||
|
])
|
||||||
])].
|
])].
|
||||||
|
|
||||||
|
|
||||||
list_online_users(_Lang) ->
|
list_online_users(Host, _Lang) ->
|
||||||
Users = [{S, U} || {U, S, R} <- ejabberd_sm:dirty_get_sessions_list()],
|
Users = [{S, U} || {U, S, R} <- ejabberd_sm:get_vh_session_list(Host)],
|
||||||
SUsers = lists:usort(Users),
|
SUsers = lists:usort(Users),
|
||||||
lists:flatmap(
|
lists:flatmap(
|
||||||
fun(SU) ->
|
fun({S, U} = SU) ->
|
||||||
[?AC("../user/" ++ su_to_list(SU) ++ "/", su_to_list(SU)), ?BR]
|
[?AC("../user/" ++ U ++ "/", su_to_list(SU)), ?BR]
|
||||||
end, SUsers).
|
end, SUsers).
|
||||||
|
|
||||||
user_info(SUser, Query, Lang) ->
|
user_info(User, Server, Query, Lang) ->
|
||||||
UJID = jlib:string_to_jid(SUser),
|
US = {jlib:nodeprep(User), jlib:nameprep(Server)},
|
||||||
User = UJID#jid.user,
|
|
||||||
Server = UJID#jid.server,
|
|
||||||
US = {UJID#jid.luser, UJID#jid.lserver},
|
|
||||||
Res = user_parse_query(User, Server, Query),
|
Res = user_parse_query(User, Server, Query),
|
||||||
Resources = ejabberd_sm:get_user_resources(User, Server),
|
Resources = ejabberd_sm:get_user_resources(User, Server),
|
||||||
FResources =
|
FResources =
|
||||||
@ -1315,11 +1421,8 @@ user_parse_query(User, Server, Query) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
user_queue(SUser, Query, Lang) ->
|
user_queue(User, Server, Query, Lang) ->
|
||||||
UJID = jlib:string_to_jid(SUser),
|
US = {jlib:nodeprep(User), jlib:nameprep(Server)},
|
||||||
User = UJID#jid.user,
|
|
||||||
Server = UJID#jid.server,
|
|
||||||
US = {UJID#jid.luser, UJID#jid.lserver},
|
|
||||||
Res = user_queue_parse_query(US, Query),
|
Res = user_queue_parse_query(US, Query),
|
||||||
Msgs = lists:keysort(3, mnesia:dirty_read({offline_msg, US})),
|
Msgs = lists:keysort(3, mnesia:dirty_read({offline_msg, US})),
|
||||||
FMsgs =
|
FMsgs =
|
||||||
@ -1409,11 +1512,8 @@ ask_to_pending(unsubscribe) -> none;
|
|||||||
ask_to_pending(Ask) -> Ask.
|
ask_to_pending(Ask) -> Ask.
|
||||||
|
|
||||||
|
|
||||||
user_roster(SUser, Query, Lang, Admin) ->
|
user_roster(User, Server, Query, Lang, Admin) ->
|
||||||
UJID = jlib:string_to_jid(SUser),
|
US = {jlib:nodeprep(User), jlib:nameprep(Server)},
|
||||||
User = UJID#jid.user,
|
|
||||||
Server = UJID#jid.server,
|
|
||||||
US = {UJID#jid.luser, UJID#jid.lserver},
|
|
||||||
Items1 = mnesia:dirty_index_read(roster, US, #roster.us),
|
Items1 = mnesia:dirty_index_read(roster, US, #roster.us),
|
||||||
Res = user_roster_parse_query(User, Server, Items1, Query, Admin),
|
Res = user_roster_parse_query(User, Server, Items1, Query, Admin),
|
||||||
Items = mnesia:dirty_index_read(roster, US, #roster.us),
|
Items = mnesia:dirty_index_read(roster, US, #roster.us),
|
||||||
@ -1556,7 +1656,7 @@ user_roster_item_parse_query(User, Server, Items, Query) ->
|
|||||||
nothing.
|
nothing.
|
||||||
|
|
||||||
|
|
||||||
list_last_activity(Lang, Integral, Period) ->
|
list_last_activity(Host, Lang, Integral, Period) ->
|
||||||
{MegaSecs, Secs, _MicroSecs} = now(),
|
{MegaSecs, Secs, _MicroSecs} = now(),
|
||||||
TimeStamp = MegaSecs * 1000000 + Secs,
|
TimeStamp = MegaSecs * 1000000 + Secs,
|
||||||
case Period of
|
case Period of
|
||||||
@ -1571,7 +1671,7 @@ list_last_activity(Lang, Integral, Period) ->
|
|||||||
Days = 31
|
Days = 31
|
||||||
end,
|
end,
|
||||||
case catch mnesia:dirty_select(
|
case catch mnesia:dirty_select(
|
||||||
last_activity, [{{last_activity, '_', '$1', '_'},
|
last_activity, [{{last_activity, {'_', Host}, '$1', '_'},
|
||||||
[{'>', '$1', TS}],
|
[{'>', '$1', TS}],
|
||||||
[{'trunc', {'/',
|
[{'trunc', {'/',
|
||||||
{'-', TimeStamp, '$1'},
|
{'-', TimeStamp, '$1'},
|
||||||
@ -1677,7 +1777,7 @@ search_running_node(SNode, [Node | Nodes]) ->
|
|||||||
search_running_node(SNode, Nodes)
|
search_running_node(SNode, Nodes)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
get_node(Node, [], Query, Lang) ->
|
get_node(global, Node, [], Query, Lang) ->
|
||||||
Res = node_parse_query(Node, Query),
|
Res = node_parse_query(Node, Query),
|
||||||
[?XC("h1", ?T("Node ") ++ atom_to_list(Node))] ++
|
[?XC("h1", ?T("Node ") ++ atom_to_list(Node))] ++
|
||||||
case Res of
|
case Res of
|
||||||
@ -1689,7 +1789,6 @@ get_node(Node, [], Query, Lang) ->
|
|||||||
[?LI([?ACT("db/", "DB Management")]),
|
[?LI([?ACT("db/", "DB Management")]),
|
||||||
?LI([?ACT("backup/", "Backup Management")]),
|
?LI([?ACT("backup/", "Backup Management")]),
|
||||||
?LI([?ACT("ports/", "Listened Ports Management")]),
|
?LI([?ACT("ports/", "Listened Ports Management")]),
|
||||||
?LI([?ACT("modules/", "Modules Management")]),
|
|
||||||
?LI([?ACT("stats/", "Statistics")])
|
?LI([?ACT("stats/", "Statistics")])
|
||||||
]),
|
]),
|
||||||
?XAE("form", [{"method", "post"}],
|
?XAE("form", [{"method", "post"}],
|
||||||
@ -1698,7 +1797,13 @@ get_node(Node, [], Query, Lang) ->
|
|||||||
?INPUTT("submit", "stop", "Stop")])
|
?INPUTT("submit", "stop", "Stop")])
|
||||||
];
|
];
|
||||||
|
|
||||||
get_node(Node, ["db"], Query, Lang) ->
|
get_node(Host, Node, [], Query, Lang) ->
|
||||||
|
[?XC("h1", ?T("Node ") ++ atom_to_list(Node)),
|
||||||
|
?XE("ul",
|
||||||
|
[?LI([?ACT("modules/", "Modules Management")])])
|
||||||
|
];
|
||||||
|
|
||||||
|
get_node(global, Node, ["db"], Query, Lang) ->
|
||||||
case rpc:call(Node, mnesia, system_info, [tables]) of
|
case rpc:call(Node, mnesia, system_info, [tables]) of
|
||||||
{badrpc, _Reason} ->
|
{badrpc, _Reason} ->
|
||||||
[?XCT("h1", "RPC call error")];
|
[?XCT("h1", "RPC call error")];
|
||||||
@ -1765,7 +1870,7 @@ get_node(Node, ["db"], Query, Lang) ->
|
|||||||
)])])]
|
)])])]
|
||||||
end;
|
end;
|
||||||
|
|
||||||
get_node(Node, ["backup"], Query, Lang) ->
|
get_node(global, Node, ["backup"], Query, Lang) ->
|
||||||
Res = node_backup_parse_query(Node, Query),
|
Res = node_backup_parse_query(Node, Query),
|
||||||
[?XC("h1", ?T("Backup Management at ") ++ atom_to_list(Node)),
|
[?XC("h1", ?T("Backup Management at ") ++ atom_to_list(Node)),
|
||||||
?XAE("form", [{"method", "post"}],
|
?XAE("form", [{"method", "post"}],
|
||||||
@ -1810,7 +1915,7 @@ get_node(Node, ["backup"], Query, Lang) ->
|
|||||||
])
|
])
|
||||||
])])];
|
])])];
|
||||||
|
|
||||||
get_node(Node, ["ports"], Query, Lang) ->
|
get_node(global, Node, ["ports"], Query, Lang) ->
|
||||||
Ports = rpc:call(Node, ejabberd_config, get_local_option, [listen]),
|
Ports = rpc:call(Node, ejabberd_config, get_local_option, [listen]),
|
||||||
Res = case catch node_ports_parse_query(Node, Ports, Query) of
|
Res = case catch node_ports_parse_query(Node, Ports, Query) of
|
||||||
submitted ->
|
submitted ->
|
||||||
@ -1832,9 +1937,9 @@ get_node(Node, ["ports"], Query, Lang) ->
|
|||||||
[node_ports_to_xhtml(NewPorts, Lang)])
|
[node_ports_to_xhtml(NewPorts, Lang)])
|
||||||
];
|
];
|
||||||
|
|
||||||
get_node(Node, ["modules"], Query, Lang) ->
|
get_node(Host, Node, ["modules"], Query, Lang) when is_list(Host) ->
|
||||||
Modules = rpc:call(Node, gen_mod, loaded_modules_with_opts, []),
|
Modules = rpc:call(Node, gen_mod, loaded_modules_with_opts, []),
|
||||||
Res = case catch node_modules_parse_query(Node, Modules, Query) of
|
Res = case catch node_modules_parse_query(Host, Node, Modules, Query) of
|
||||||
submitted ->
|
submitted ->
|
||||||
ok;
|
ok;
|
||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
@ -1843,7 +1948,8 @@ get_node(Node, ["modules"], Query, Lang) ->
|
|||||||
_ ->
|
_ ->
|
||||||
nothing
|
nothing
|
||||||
end,
|
end,
|
||||||
NewModules = lists:sort(rpc:call(Node, gen_mod, loaded_modules_with_opts, [])),
|
NewModules = lists:sort(
|
||||||
|
rpc:call(Node, gen_mod, loaded_modules_with_opts, [Host])),
|
||||||
[?XC("h1", ?T("Modules at ") ++ atom_to_list(Node))] ++
|
[?XC("h1", ?T("Modules at ") ++ atom_to_list(Node))] ++
|
||||||
case Res of
|
case Res of
|
||||||
ok -> [?CT("submitted"), ?P];
|
ok -> [?CT("submitted"), ?P];
|
||||||
@ -1854,7 +1960,7 @@ get_node(Node, ["modules"], Query, Lang) ->
|
|||||||
[node_modules_to_xhtml(NewModules, Lang)])
|
[node_modules_to_xhtml(NewModules, Lang)])
|
||||||
];
|
];
|
||||||
|
|
||||||
get_node(Node, ["stats"], Query, Lang) ->
|
get_node(global, Node, ["stats"], Query, Lang) ->
|
||||||
UpTime = rpc:call(Node, erlang, statistics, [wall_clock]),
|
UpTime = rpc:call(Node, erlang, statistics, [wall_clock]),
|
||||||
UpTimeS = io_lib:format("~.3f", [element(1, UpTime)/1000]),
|
UpTimeS = io_lib:format("~.3f", [element(1, UpTime)/1000]),
|
||||||
CPUTime = rpc:call(Node, erlang, statistics, [runtime]),
|
CPUTime = rpc:call(Node, erlang, statistics, [runtime]),
|
||||||
@ -1897,7 +2003,7 @@ get_node(Node, ["stats"], Query, Lang) ->
|
|||||||
])
|
])
|
||||||
])];
|
])];
|
||||||
|
|
||||||
get_node(Node, NPath, Query, Lang) ->
|
get_node(Host, Node, NPath, Query, Lang) ->
|
||||||
[?XCT("h1", "Not found")].
|
[?XCT("h1", "Not found")].
|
||||||
|
|
||||||
|
|
||||||
@ -2133,7 +2239,7 @@ node_modules_to_xhtml(Modules, Lang) ->
|
|||||||
)]
|
)]
|
||||||
)]).
|
)]).
|
||||||
|
|
||||||
node_modules_parse_query(Node, Modules, Query) ->
|
node_modules_parse_query(Host, Node, Modules, Query) ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({Module, _Opts1}) ->
|
fun({Module, _Opts1}) ->
|
||||||
SModule = atom_to_list(Module),
|
SModule = atom_to_list(Module),
|
||||||
@ -2143,13 +2249,13 @@ node_modules_parse_query(Node, Modules, Query) ->
|
|||||||
lists:keysearch("opts" ++ SModule, 1, Query),
|
lists:keysearch("opts" ++ SModule, 1, Query),
|
||||||
{ok, Tokens, _} = erl_scan:string(SOpts ++ "."),
|
{ok, Tokens, _} = erl_scan:string(SOpts ++ "."),
|
||||||
{ok, Opts} = erl_parse:parse_term(Tokens),
|
{ok, Opts} = erl_parse:parse_term(Tokens),
|
||||||
rpc:call(Node, gen_mod, stop_module, [Module]),
|
rpc:call(Node, gen_mod, stop_module, [Host, Module]),
|
||||||
rpc:call(Node, gen_mod, start_module, [Module, Opts]),
|
rpc:call(Node, gen_mod, start_module, [Host, Module, Opts]),
|
||||||
throw(submitted);
|
throw(submitted);
|
||||||
_ ->
|
_ ->
|
||||||
case lists:keysearch("stop" ++ SModule, 1, Query) of
|
case lists:keysearch("stop" ++ SModule, 1, Query) of
|
||||||
{value, _} ->
|
{value, _} ->
|
||||||
rpc:call(Node, gen_mod, stop_module, [Module]),
|
rpc:call(Node, gen_mod, stop_module, [Host, Module]),
|
||||||
throw(submitted);
|
throw(submitted);
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
@ -2165,7 +2271,7 @@ node_modules_parse_query(Node, Modules, Query) ->
|
|||||||
Module = list_to_atom(SModule),
|
Module = list_to_atom(SModule),
|
||||||
{ok, Tokens, _} = erl_scan:string(SOpts ++ "."),
|
{ok, Tokens, _} = erl_scan:string(SOpts ++ "."),
|
||||||
{ok, Opts} = erl_parse:parse_term(Tokens),
|
{ok, Opts} = erl_parse:parse_term(Tokens),
|
||||||
rpc:call(Node, gen_mod, start_module, [Module, Opts]),
|
rpc:call(Node, gen_mod, start_module, [Host, Module, Opts]),
|
||||||
throw(submitted);
|
throw(submitted);
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
|
Loading…
Reference in New Issue
Block a user