mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
Fix core files
This commit is contained in:
parent
13fad04d14
commit
58bed2cbff
@ -98,7 +98,7 @@ register_mechanism(Mechanism, Module, RequirePlainPassword) ->
|
|||||||
% {error, "invalid-authzid"};
|
% {error, "invalid-authzid"};
|
||||||
% JID ->
|
% JID ->
|
||||||
% LUser = jlib:nodeprep(xml:get_attr_s(username, Props)),
|
% LUser = jlib:nodeprep(xml:get_attr_s(username, Props)),
|
||||||
% {U, S, R} = jlib:jid_tolower(JID),
|
% {U, S, R} = jlib:short_prepd_jid(JID),
|
||||||
% case R of
|
% case R of
|
||||||
% "" ->
|
% "" ->
|
||||||
% {error, "invalid-authzid"};
|
% {error, "invalid-authzid"};
|
||||||
|
@ -296,8 +296,8 @@ send_service_message_all_mucs(Subject, AnnouncementText) ->
|
|||||||
Message = io_lib:format("~s~n~s", [Subject, AnnouncementText]),
|
Message = io_lib:format("~s~n~s", [Subject, AnnouncementText]),
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun(ServerHost) ->
|
fun(ServerHost) ->
|
||||||
MUCHost = gen_mod:expand_host_name(
|
MUCHost = gen_mod:get_module_opt_host(
|
||||||
ServerHost, mod_muc, "conference"),
|
ServerHost, mod_muc, "conference.@HOST@"),
|
||||||
MUCHostB = list_to_binary(MUCHost),
|
MUCHostB = list_to_binary(MUCHost),
|
||||||
mod_muc:broadcast_service_message(MUCHostB, Message)
|
mod_muc:broadcast_service_message(MUCHostB, Message)
|
||||||
end,
|
end,
|
||||||
|
@ -490,6 +490,15 @@ process_host_term(Term, Host, State) ->
|
|||||||
State;
|
State;
|
||||||
{odbc_server, ODBC_server} ->
|
{odbc_server, ODBC_server} ->
|
||||||
add_option({odbc_server, Host}, ODBC_server, State);
|
add_option({odbc_server, Host}, ODBC_server, State);
|
||||||
|
{auth_method, Methods} ->
|
||||||
|
{Methods2, StorageOption} = replace_storage_auth(Host, Methods),
|
||||||
|
State2 = case StorageOption of
|
||||||
|
{auth_storage, Storage} ->
|
||||||
|
add_option({auth_storage, Host}, Storage, State);
|
||||||
|
undefined ->
|
||||||
|
State
|
||||||
|
end,
|
||||||
|
add_option({auth_method, Host}, Methods2, State2);
|
||||||
{Opt, Val} ->
|
{Opt, Val} ->
|
||||||
add_option({Opt, Host}, Val, State)
|
add_option({Opt, Host}, Val, State)
|
||||||
end.
|
end.
|
||||||
@ -720,3 +729,35 @@ mnesia_write_objects(List) when is_list(List) ->
|
|||||||
true = lists:all(fun (I) ->
|
true = lists:all(fun (I) ->
|
||||||
ok =:= mnesia:write(I)
|
ok =:= mnesia:write(I)
|
||||||
end, List).
|
end, List).
|
||||||
|
|
||||||
|
%% Replace internal and odbc auth_methods with storage.
|
||||||
|
%% Only one storage type can be used, either internal or odbc.
|
||||||
|
replace_storage_auth(Host, Val) when not is_list(Val) ->
|
||||||
|
replace_storage_auth(Host, [Val]);
|
||||||
|
replace_storage_auth(Host, Val) ->
|
||||||
|
replace_storage_auth(Host, Val, [], undefined).
|
||||||
|
|
||||||
|
replace_storage_auth(_Host, [], Val2, Storage) ->
|
||||||
|
{lists:reverse(Val2), Storage};
|
||||||
|
|
||||||
|
replace_storage_auth(Host, [internal = Val | ValT], Val2, undefined) ->
|
||||||
|
Storage = {auth_storage, mnesia},
|
||||||
|
?WARNING_MSG("The auth method '~p' is deprecated.~nReplace it with 'storage'"
|
||||||
|
" and also add this option: ~n~p.", [Val, Storage]),
|
||||||
|
replace_storage_auth(Host, ValT, [storage | Val2], Storage);
|
||||||
|
|
||||||
|
replace_storage_auth(Host, [odbc = Val | ValT], Val2, undefined) ->
|
||||||
|
Storage = {auth_storage, odbc},
|
||||||
|
?WARNING_MSG("The auth method '~p' is deprecated.~nReplace it with 'storage'"
|
||||||
|
" and also add this option: ~n~p.", [Val, Storage]),
|
||||||
|
replace_storage_auth(Host, ValT, [storage | Val2], Storage);
|
||||||
|
|
||||||
|
replace_storage_auth(Host, [Val | ValT], Val2, Storage)
|
||||||
|
when (Val /= internal) and (Val /= odbc) ->
|
||||||
|
replace_storage_auth(Host, ValT, [Val | Val2], Storage);
|
||||||
|
|
||||||
|
replace_storage_auth(Host, [Val | _ValT], _Val2, Storage) ->
|
||||||
|
?CRITICAL_MSG("The auth method '~p' conflicts with~n~p in the host \"~p\"."
|
||||||
|
"~nOnly one of them can be used in each host.",
|
||||||
|
[Val, Storage, Host]),
|
||||||
|
throw({unacceptable_auth_conflict, Host, Val, Storage}).
|
||||||
|
@ -327,7 +327,7 @@ run1([{_Seq, Module, Function} | Ls], Hook, Args) ->
|
|||||||
[Reason, {Hook, Args}]),
|
[Reason, {Hook, Args}]),
|
||||||
run1(Ls, Hook, Args);
|
run1(Ls, Hook, Args);
|
||||||
stop ->
|
stop ->
|
||||||
ok;
|
stop;
|
||||||
_ ->
|
_ ->
|
||||||
run1(Ls, Hook, Args)
|
run1(Ls, Hook, Args)
|
||||||
end.
|
end.
|
||||||
|
@ -1,9 +1,22 @@
|
|||||||
%%%-------------------------------------------------------------------
|
%%%-------------------------------------------------------------------
|
||||||
%%% File : ejabberd_hosts.erl
|
%%% File : ejabberd_hosts.erl
|
||||||
%%% Author : Alexey Shchepin <alexey@process-one.net>
|
%%% Author : Alexey Shchepin <alexey@process-one.net>
|
||||||
%%% Description : Synchronises running VHosts with the hosts table in the database.
|
%%% Description : Synchronises running VHosts with the hosts table in the Mnesia database.
|
||||||
%%% Created : 16 Nov 2007 by Alexey Shchepin <alexey@process-one.net>
|
%%% Created : 16 Nov 2007 by Alexey Shchepin <alexey@process-one.net>
|
||||||
%%%-------------------------------------------------------------------
|
%%%-------------------------------------------------------------------
|
||||||
|
|
||||||
|
%%% Database schema (version / storage / table)
|
||||||
|
%%%
|
||||||
|
%%% 3.0.0-alpha-x / mnesia / hosts
|
||||||
|
%%% host = string()
|
||||||
|
%%% clusterid = integer()
|
||||||
|
%%% config = string()
|
||||||
|
%%%
|
||||||
|
%%% 3.0.0-alpha-x / odbc / hosts
|
||||||
|
%%% host = varchar150
|
||||||
|
%%% clusterid = integer
|
||||||
|
%%% config = text
|
||||||
|
|
||||||
-module(ejabberd_hosts).
|
-module(ejabberd_hosts).
|
||||||
|
|
||||||
-behaviour(gen_server).
|
-behaviour(gen_server).
|
||||||
@ -50,7 +63,9 @@
|
|||||||
-include_lib("stdlib/include/ms_transform.hrl").
|
-include_lib("stdlib/include/ms_transform.hrl").
|
||||||
|
|
||||||
-record(state, {state=wait_odbc,
|
-record(state, {state=wait_odbc,
|
||||||
|
backend=mnesia,
|
||||||
odbc_wait_time=120}).
|
odbc_wait_time=120}).
|
||||||
|
-record(hosts, {host, clusterid, config}).
|
||||||
|
|
||||||
-define(RELOAD_INTERVAL, timer:seconds(60)).
|
-define(RELOAD_INTERVAL, timer:seconds(60)).
|
||||||
-define(ODBC_STARTUP_TIME, 120). % 2minute limit for ODBC startup.
|
-define(ODBC_STARTUP_TIME, 120). % 2minute limit for ODBC startup.
|
||||||
@ -65,32 +80,25 @@ reload() ->
|
|||||||
%% Creates a vhost in the system.
|
%% Creates a vhost in the system.
|
||||||
register(Host) when is_list(Host) -> ?MODULE:register(Host, "").
|
register(Host) when is_list(Host) -> ?MODULE:register(Host, "").
|
||||||
register(Host, Config) when is_list(Host), is_list(Config) ->
|
register(Host, Config) when is_list(Host), is_list(Config) ->
|
||||||
true = jlib:is_nodename(Host),
|
true = exmpp_stringprep:is_node(Host),
|
||||||
ID = ejabberd_config:get_local_option(clusterid),
|
ID = get_clusterid(),
|
||||||
case ejabberd_odbc:sql_query(?MYNAME,
|
H = #hosts{host = Host, clusterid = ID, config = Config},
|
||||||
["INSERT INTO hosts (clusterid,host,config) VALUES (",
|
ok = gen_storage:dirty_write(Host, H),
|
||||||
integer_to_list(ID), ", '",Host,"','",Config,"')"]) of
|
reload(),
|
||||||
{updated, 1} ->
|
ok.
|
||||||
reload(),
|
|
||||||
ok;
|
|
||||||
{error, E} -> {error, E}
|
|
||||||
end.
|
|
||||||
|
|
||||||
%% Removes a vhost from the system,
|
%% Removes a vhost from the system,
|
||||||
%% XXX deleting all ODBC data.
|
%% XXX deleting all ODBC data.
|
||||||
remove(Host) when is_list(Host) ->
|
remove(Host) when is_list(Host) ->
|
||||||
true = jlib:is_nodename(Host),
|
true = exmpp_stringprep:is_node(Host),
|
||||||
ID = ejabberd_config:get_local_option(clusterid),
|
ID = get_clusterid(),
|
||||||
case ejabberd_odbc:sql_query(?MYNAME,
|
gen_storage:dirty_delete_where(
|
||||||
["DELETE FROM hosts "
|
Host, hosts,
|
||||||
"WHERE clusterid=",
|
[{'andalso',
|
||||||
integer_to_list(ID), " AND host='",Host,"'"]) of
|
{'==', clusterid, ID},
|
||||||
{updated, 1} ->
|
{'==', host, Host}}]),
|
||||||
reload(),
|
reload(),
|
||||||
ok;
|
ok.
|
||||||
{updated, 0} -> {error, no_such_host};
|
|
||||||
{error, E} -> {error, E}
|
|
||||||
end.
|
|
||||||
|
|
||||||
registered() ->
|
registered() ->
|
||||||
mnesia:dirty_select(local_config,
|
mnesia:dirty_select(local_config,
|
||||||
@ -136,9 +144,11 @@ start_link() ->
|
|||||||
%% Description: Initiates the server
|
%% Description: Initiates the server
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
init([]) ->
|
init([]) ->
|
||||||
|
Backend = mnesia, %%+++ TODO: allow to configure this in ejabberd.cfg
|
||||||
configure_static_hosts(),
|
configure_static_hosts(),
|
||||||
|
get_clusterid(), %% this is to report an error if the option wasn't configured
|
||||||
%% Wait up to 120 seconds for odbc to start
|
%% Wait up to 120 seconds for odbc to start
|
||||||
{ok, #state{state=wait_odbc,odbc_wait_time=?ODBC_STARTUP_TIME}, timer:seconds(1)}.
|
{ok, #state{state=wait_odbc,backend=Backend,odbc_wait_time=?ODBC_STARTUP_TIME}, timer:seconds(1)}.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
|
%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
|
||||||
@ -169,10 +179,27 @@ handle_cast(_Msg, State) ->
|
|||||||
%% Description: Handling all non call/cast messages
|
%% Description: Handling all non call/cast messages
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Wait for odbc to start.
|
%% Wait for odbc to start.
|
||||||
handle_info(timeout, State = #state{state=wait_odbc,odbc_wait_time=N}) when N > 0 ->
|
handle_info(timeout, State = #state{state=wait_odbc,backend=Backend,odbc_wait_time=N}) when N > 0 ->
|
||||||
case ejabberd_odbc:running(?MYNAME) of
|
case (Backend /= odbc) orelse ejabberd_odbc:running(?MYNAME) of
|
||||||
true ->
|
true ->
|
||||||
?DEBUG("ejabberd_hosts: odbc now running.",[]),
|
?DEBUG("ejabberd_hosts: odbc now running.",[]),
|
||||||
|
|
||||||
|
%% The table 'hosts' is defined in gen_storage as being for the "localhost" vhost
|
||||||
|
Host = ?MYNAME,
|
||||||
|
HostB = list_to_binary(Host),
|
||||||
|
gen_storage:create_table(Backend, HostB, hosts,
|
||||||
|
[{disc_only_copies, [node()]},
|
||||||
|
{odbc_host, Host},
|
||||||
|
{attributes, record_info(fields, hosts)},
|
||||||
|
{types, [{host, text},
|
||||||
|
{clusterid, int},
|
||||||
|
{config, text}]}]),
|
||||||
|
|
||||||
|
%% Now let's add the default vhost: "localhost"
|
||||||
|
gen_storage:dirty_write(Host, #hosts{host = Host,
|
||||||
|
clusterid = 1,
|
||||||
|
config = ""}),
|
||||||
|
|
||||||
self() ! reload,
|
self() ! reload,
|
||||||
timer:send_interval(?RELOAD_INTERVAL, reload),
|
timer:send_interval(?RELOAD_INTERVAL, reload),
|
||||||
{noreply, State#state{state=running,odbc_wait_time=0}};
|
{noreply, State#state{state=running,odbc_wait_time=0}};
|
||||||
@ -305,35 +332,29 @@ stop_host(Host) ->
|
|||||||
%% Get the current vhost list from a variety of sources (ODBC, internal)
|
%% Get the current vhost list from a variety of sources (ODBC, internal)
|
||||||
get_hosts(ejabberd) -> ?MYHOSTS;
|
get_hosts(ejabberd) -> ?MYHOSTS;
|
||||||
get_hosts(odbc) ->
|
get_hosts(odbc) ->
|
||||||
ClusterID = ejabberd_config:get_local_option(clusterid),
|
ClusterID = get_clusterid(),
|
||||||
case ejabberd_odbc:sql_query(
|
case gen_storage:dirty_select(?MYNAME, hosts, [{'=', clusterid, ClusterID}]) of
|
||||||
?MYNAME,
|
Hosts when is_list(Hosts) ->
|
||||||
["select host from hosts where clusterid = ",
|
lists:map(fun (#hosts{host = Host}) ->
|
||||||
integer_to_list(ClusterID)]) of
|
case exmpp_stringprep:nameprep(Host) of
|
||||||
{selected, ["host"], SHosts} ->
|
|
||||||
lists:map(fun ({Host}) ->
|
|
||||||
case jlib:nameprep(Host) of
|
|
||||||
error ->
|
error ->
|
||||||
erlang:error({bad_vhost_name, Host});
|
erlang:error({bad_vhost_name, Host});
|
||||||
Name ->
|
Name ->
|
||||||
Name
|
Name
|
||||||
end
|
end
|
||||||
end, SHosts);
|
end, Hosts);
|
||||||
E ->
|
E ->
|
||||||
erlang:error({get_hosts_odbc_error, E})
|
erlang:error({get_hosts_error, E})
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% Retreive the text format config for host Host from ODBC and covert
|
%% Retreive the text format config for host Host from ODBC and covert
|
||||||
%% it into a {host, Host, Config} tuple.
|
%% it into a {host, Host, Config} tuple.
|
||||||
get_host_config(odbc, Host) ->
|
get_host_config(odbc, Host) ->
|
||||||
case ejabberd_odbc:sql_query(
|
case gen_storage:dirty_read(?MYNAME, hosts, Host) of
|
||||||
?MYNAME,
|
[] ->
|
||||||
["select config from hosts where host = '",
|
|
||||||
Host, "'"]) of
|
|
||||||
{selected, ["config"], [{Config}]} ->
|
|
||||||
config_from_string(Host, Config);
|
|
||||||
{selected, ["config"], []} ->
|
|
||||||
erlang:error({no_such_host, Host});
|
erlang:error({no_such_host, Host});
|
||||||
|
[H] ->
|
||||||
|
config_from_string(Host, H#hosts.config);
|
||||||
E ->
|
E ->
|
||||||
erlang:error({host_config_error, E})
|
erlang:error({host_config_error, E})
|
||||||
end.
|
end.
|
||||||
@ -401,3 +422,12 @@ reconfigure_host_cert(Host) ->
|
|||||||
false ->
|
false ->
|
||||||
no_cert
|
no_cert
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
get_clusterid() ->
|
||||||
|
case ejabberd_config:get_local_option(clusterid) of
|
||||||
|
ID when is_integer(ID) ->
|
||||||
|
ID;
|
||||||
|
Other ->
|
||||||
|
?ERROR_MSG("The option {clusterid, INTEGER}. was configured to: ~p", [Other]),
|
||||||
|
1
|
||||||
|
end.
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
-include_lib("exmpp/include/exmpp_client.hrl").
|
-include_lib("exmpp/include/exmpp_client.hrl").
|
||||||
|
|
||||||
%% Copied from mod_private.erl
|
%% Copied from mod_private.erl
|
||||||
-record(private_storage, {usns, xml}).
|
-record(private_storage, {user_host_ns, xml}).
|
||||||
|
|
||||||
%%-define(ERROR_MSG(M,Args),io:format(M,Args)).
|
%%-define(ERROR_MSG(M,Args),io:format(M,Args)).
|
||||||
%%-define(INFO_MSG(M,Args),ok).
|
%%-define(INFO_MSG(M,Args),ok).
|
||||||
@ -465,7 +465,7 @@ make_xinclude(Fn) ->
|
|||||||
%% @doc Extract user information and print it.
|
%% @doc Extract user information and print it.
|
||||||
export_user(Fd, Username, Host) ->
|
export_user(Fd, Username, Host) ->
|
||||||
try extract_user(Username, Host) of
|
try extract_user(Username, Host) of
|
||||||
UserString ->
|
UserString when is_list(UserString) ->
|
||||||
print(Fd, UserString)
|
print(Fd, UserString)
|
||||||
catch
|
catch
|
||||||
E1:E2 ->
|
E1:E2 ->
|
||||||
@ -543,7 +543,7 @@ extract_user_info(vcard, Username, Host) ->
|
|||||||
%%%% Interface with ejabberd offline storage
|
%%%% Interface with ejabberd offline storage
|
||||||
|
|
||||||
%% Copied from mod_offline.erl and customized
|
%% Copied from mod_offline.erl and customized
|
||||||
-record(offline_msg, {us, timestamp, expire, from, to, packet}).
|
-record(offline_msg, {user_host, timestamp, expire, from, to, packet}).
|
||||||
mnesia_pop_offline_messages(Ls, User, Server) ->
|
mnesia_pop_offline_messages(Ls, User, Server) ->
|
||||||
try
|
try
|
||||||
LUser = User,
|
LUser = User,
|
||||||
@ -556,31 +556,31 @@ mnesia_pop_offline_messages(Ls, User, Server) ->
|
|||||||
end,
|
end,
|
||||||
case mnesia:transaction(F) of
|
case mnesia:transaction(F) of
|
||||||
{atomic, Rs} ->
|
{atomic, Rs} ->
|
||||||
TS = now(),
|
TS = make_timestamp(),
|
||||||
Ls ++ lists:map(
|
Ls ++ lists:map(
|
||||||
fun(R) ->
|
fun(R) ->
|
||||||
Packet = R#offline_msg.packet,
|
[Packet] = exmpp_xml:parse_document(R#offline_msg.packet, [names_as_atom]),
|
||||||
FromString = exmpp_jid:prep_to_list(R#offline_msg.from),
|
FromString = exmpp_jid:prep_to_list(R#offline_msg.from),
|
||||||
Packet2 = exmpp_xml:set_attribute(Packet, "from", FromString),
|
Packet2 = exmpp_xml:set_attribute(Packet, "from", FromString),
|
||||||
Packet3 = Packet2#xmlel{ns = ?NS_JABBER_CLIENT},
|
Packet3 = Packet2#xmlel{ns = ?NS_JABBER_CLIENT},
|
||||||
exmpp_xml:append_children(
|
exmpp_xml:append_children(
|
||||||
Packet3,
|
Packet3,
|
||||||
[jlib:timestamp_to_xml(
|
[jlib:timestamp_to_xml(
|
||||||
calendar:now_to_universal_time(
|
calendar:gregorian_seconds_to_datetime(
|
||||||
R#offline_msg.timestamp),
|
R#offline_msg.timestamp),
|
||||||
utc,
|
utc,
|
||||||
exmpp_jid:make("", Server, ""),
|
exmpp_jid:make("", Server, ""),
|
||||||
"Offline Storage"),
|
"Offline Storage"),
|
||||||
%% TODO: Delete the next three lines once XEP-0091 is Obsolete
|
%% TODO: Delete the next three lines once XEP-0091 is Obsolete
|
||||||
jlib:timestamp_to_xml(
|
jlib:timestamp_to_xml(
|
||||||
calendar:now_to_universal_time(
|
calendar:gregorian_seconds_to_datetime(
|
||||||
R#offline_msg.timestamp))]
|
R#offline_msg.timestamp))]
|
||||||
)
|
)
|
||||||
end,
|
end,
|
||||||
lists:filter(
|
lists:filter(
|
||||||
fun(R) ->
|
fun(R) ->
|
||||||
case R#offline_msg.expire of
|
case R#offline_msg.expire of
|
||||||
never ->
|
0 ->
|
||||||
true;
|
true;
|
||||||
TimeStamp ->
|
TimeStamp ->
|
||||||
TS < TimeStamp
|
TS < TimeStamp
|
||||||
@ -595,15 +595,18 @@ mnesia_pop_offline_messages(Ls, User, Server) ->
|
|||||||
Ls
|
Ls
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
make_timestamp() ->
|
||||||
|
{MegaSecs, Secs, _MicroSecs} = now(),
|
||||||
|
MegaSecs * 1000000 + Secs.
|
||||||
|
|
||||||
%%%==================================
|
%%%==================================
|
||||||
%%%% Interface with ejabberd private storage
|
%%%% Interface with ejabberd private storage
|
||||||
|
|
||||||
get_user_private_mnesia(Username, Host) ->
|
get_user_private_mnesia(Username, Host) ->
|
||||||
ListNsEl = mnesia:dirty_select(private_storage,
|
ListNsEl = mnesia:dirty_select(private_storage,
|
||||||
[{#private_storage{usns={?LTB(Username), ?LTB(Host), '$1'}, xml = '$2'},
|
[{#private_storage{user_host_ns={?LTB(Username), ?LTB(Host), '$1'}, xml = '$2'},
|
||||||
[], ['$$']}]),
|
[], ['$$']}]),
|
||||||
Els = [exmpp_xml:document_to_list(El) || [_Ns, El] <- ListNsEl],
|
Els = [lists:flatten(exmpp_xml:document_to_list(El)) || [_Ns, El] <- ListNsEl],
|
||||||
case lists:flatten(Els) of
|
case lists:flatten(Els) of
|
||||||
"" -> "";
|
"" -> "";
|
||||||
ElsString ->
|
ElsString ->
|
||||||
|
107
src/ejd2odbc.erl
107
src/ejd2odbc.erl
@ -30,6 +30,7 @@
|
|||||||
%% External exports
|
%% External exports
|
||||||
-export([export_passwd/2,
|
-export([export_passwd/2,
|
||||||
export_roster/2,
|
export_roster/2,
|
||||||
|
export_roster_group/2,
|
||||||
export_offline/2,
|
export_offline/2,
|
||||||
export_last/2,
|
export_last/2,
|
||||||
export_vcard/2,
|
export_vcard/2,
|
||||||
@ -41,10 +42,10 @@
|
|||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("mod_roster.hrl").
|
-include("mod_roster.hrl").
|
||||||
|
|
||||||
-record(offline_msg, {us, timestamp, expire, from, to, packet}).
|
-record(offline_msg, {user_host, timestamp, expire, from, to, packet}).
|
||||||
-record(last_activity, {us, timestamp, status}).
|
-record(last_activity, {user_host, timestamp, status}).
|
||||||
-record(vcard, {us, vcard}).
|
-record(vcard, {user_host, vcard}).
|
||||||
-record(vcard_search, {us,
|
-record(vcard_search, {user_host,
|
||||||
user, luser,
|
user, luser,
|
||||||
fn, lfn,
|
fn, lfn,
|
||||||
family, lfamily,
|
family, lfamily,
|
||||||
@ -58,7 +59,7 @@
|
|||||||
orgname, lorgname,
|
orgname, lorgname,
|
||||||
orgunit, lorgunit
|
orgunit, lorgunit
|
||||||
}).
|
}).
|
||||||
-record(private_storage, {usns, xml}).
|
-record(private_storage, {user_host_ns, xml}).
|
||||||
|
|
||||||
-define(MAX_RECORDS_PER_TRANSACTION, 1000).
|
-define(MAX_RECORDS_PER_TRANSACTION, 1000).
|
||||||
|
|
||||||
@ -79,9 +80,9 @@ export_passwd(Server, Output) ->
|
|||||||
when LServer == Host ->
|
when LServer == Host ->
|
||||||
Username = ejabberd_odbc:escape(LUser),
|
Username = ejabberd_odbc:escape(LUser),
|
||||||
Pass = ejabberd_odbc:escape(Password),
|
Pass = ejabberd_odbc:escape(Password),
|
||||||
["delete from users where username='", Username ,"';"
|
["delete from users where host='", Server, "' and username='", Username ,"';\n"
|
||||||
"insert into users(username, password) "
|
"insert into users(host, username, password) "
|
||||||
"values ('", Username, "', '", Pass, "');"];
|
"values ('", Server, "', '", Username, "', '", Pass, "');\n"];
|
||||||
(_Host, _R) ->
|
(_Host, _R) ->
|
||||||
[]
|
[]
|
||||||
end).
|
end).
|
||||||
@ -89,28 +90,37 @@ export_passwd(Server, Output) ->
|
|||||||
export_roster(ServerS, Output) ->
|
export_roster(ServerS, Output) ->
|
||||||
Server = list_to_binary(ServerS),
|
Server = list_to_binary(ServerS),
|
||||||
export_common(
|
export_common(
|
||||||
Server, roster, Output,
|
Server, rosteritem, Output,
|
||||||
fun(Host, #roster{usj = {LUser, LServer, {N, D, Res} = _LJID}} = R)
|
fun(Host, #rosteritem{user_host_jid = {LUser, LServer, {N, D, Res} = _LJID}} = R)
|
||||||
when LServer == Host ->
|
when LServer == Host ->
|
||||||
Username = ejabberd_odbc:escape(LUser),
|
Username = ejabberd_odbc:escape(LUser),
|
||||||
SJID = ejabberd_odbc:escape(exmpp_jid:to_list(N, D, Res)),
|
SJID = ejabberd_odbc:escape(exmpp_jid:to_list(N, D, Res)),
|
||||||
ItemVals = record_to_string(R),
|
ItemVals = record_to_string(R, ServerS),
|
||||||
ItemGroups = groups_to_string(R),
|
|
||||||
["delete from rosterusers "
|
["delete from rosterusers "
|
||||||
" where username='", Username, "' "
|
" where username='", Username, "' "
|
||||||
" and jid='", SJID, "';"
|
" and jid='", SJID, "';\n"
|
||||||
"insert into rosterusers("
|
"insert into rosterusers("
|
||||||
" username, jid, nick, "
|
" host, username, jid, nick, "
|
||||||
" subscription, ask, askmessage, "
|
" subscription, ask, askmessage, "
|
||||||
" server, subscribe, type) "
|
" server, subscribe, type) "
|
||||||
" values ", ItemVals, ";"
|
" values ", ItemVals, ";\n"];
|
||||||
"delete from rostergroups "
|
(_Host, _R) ->
|
||||||
" where username='", Username, "' "
|
[]
|
||||||
" and jid='", SJID, "';",
|
end).
|
||||||
[["insert into rostergroups("
|
|
||||||
" username, jid, grp) "
|
export_roster_group(ServerS, Output) ->
|
||||||
" values ", ItemGroup, ";"] ||
|
Server = list_to_binary(ServerS),
|
||||||
ItemGroup <- ItemGroups]];
|
export_common(
|
||||||
|
Server, rostergroup, Output,
|
||||||
|
fun(Host, #rostergroup{user_host_jid = {_LUser, LServer, _LJID}} = R)
|
||||||
|
when LServer == Host ->
|
||||||
|
ItemGroup = group_to_string(R, ServerS),
|
||||||
|
[%%"delete from rostergroups"
|
||||||
|
%%" where username='", Username, "'"
|
||||||
|
%%" and host='", ServerS, "'"
|
||||||
|
%%" and jid='", SJID, "';"
|
||||||
|
"insert into rostergroups(host, username, jid, grp)"
|
||||||
|
" values ", ItemGroup, ";\n"];
|
||||||
(_Host, _R) ->
|
(_Host, _R) ->
|
||||||
[]
|
[]
|
||||||
end).
|
end).
|
||||||
@ -118,33 +128,34 @@ export_roster(ServerS, Output) ->
|
|||||||
export_offline(Server, Output) ->
|
export_offline(Server, Output) ->
|
||||||
export_common(
|
export_common(
|
||||||
Server, offline_msg, Output,
|
Server, offline_msg, Output,
|
||||||
fun(Host, #offline_msg{us = {LUser, LServer},
|
fun(Host, #offline_msg{user_host = {LUser, LServer},
|
||||||
timestamp = TimeStamp,
|
timestamp = TimeStamp,
|
||||||
from = From,
|
from = From,
|
||||||
to = To,
|
to = To,
|
||||||
packet = Packet})
|
packet = PacketString})
|
||||||
when LServer == Host ->
|
when LServer == Host ->
|
||||||
Username = ejabberd_odbc:escape(LUser),
|
Username = ejabberd_odbc:escape(LUser),
|
||||||
|
[Packet] = exmpp_xml:parse_document(PacketString, [names_as_atom]),
|
||||||
Packet0 = exmpp_stanza:set_jids(Packet,
|
Packet0 = exmpp_stanza:set_jids(Packet,
|
||||||
exmpp_jid:to_list(From),
|
exmpp_jid:to_list(From),
|
||||||
exmpp_jid:to_list(To)),
|
exmpp_jid:to_list(To)),
|
||||||
Packet0b = exmpp_xml:append_child(Packet0,
|
Packet0b = exmpp_xml:append_child(Packet0,
|
||||||
jlib:timestamp_to_xml(
|
jlib:timestamp_to_xml(
|
||||||
calendar:now_to_universal_time(TimeStamp),
|
calendar:gregorian_seconds_to_datetime(TimeStamp),
|
||||||
utc,
|
utc,
|
||||||
exmpp_jid:make("", Server, ""),
|
exmpp_jid:make("", Server, ""),
|
||||||
"Offline Storage")),
|
"Offline Storage")),
|
||||||
%% TODO: Delete the next three lines once XEP-0091 is Obsolete
|
%% TODO: Delete the next three lines once XEP-0091 is Obsolete
|
||||||
Packet1 = exmpp_xml:append_child(Packet0b,
|
Packet1 = exmpp_xml:append_child(Packet0b,
|
||||||
jlib:timestamp_to_xml(
|
jlib:timestamp_to_xml(
|
||||||
calendar:now_to_universal_time(TimeStamp))),
|
calendar:gregorian_seconds_to_datetime(TimeStamp))),
|
||||||
XML =
|
XML =
|
||||||
ejabberd_odbc:escape(
|
ejabberd_odbc:escape(
|
||||||
exmpp_xml:document_to_list(Packet1)),
|
exmpp_xml:document_to_list(Packet1)),
|
||||||
["insert into spool(username, xml) "
|
["insert into spool(host, username, xml) "
|
||||||
"values ('", Username, "', '",
|
"values ('", Server, "', '", Username, "', '",
|
||||||
XML,
|
XML,
|
||||||
"');"];
|
"');\n"];
|
||||||
(_Host, _R) ->
|
(_Host, _R) ->
|
||||||
[]
|
[]
|
||||||
end).
|
end).
|
||||||
@ -153,16 +164,16 @@ export_last(ServerS, Output) ->
|
|||||||
Server = list_to_binary(ServerS),
|
Server = list_to_binary(ServerS),
|
||||||
export_common(
|
export_common(
|
||||||
Server, last_activity, Output,
|
Server, last_activity, Output,
|
||||||
fun(Host, #last_activity{us = {LUser, LServer},
|
fun(Host, #last_activity{user_host = {LUser, LServer},
|
||||||
timestamp = TimeStamp,
|
timestamp = TimeStamp,
|
||||||
status = Status})
|
status = Status})
|
||||||
when LServer == Host ->
|
when LServer == Host ->
|
||||||
Username = ejabberd_odbc:escape(LUser),
|
Username = ejabberd_odbc:escape(LUser),
|
||||||
Seconds = ejabberd_odbc:escape(integer_to_list(TimeStamp)),
|
Seconds = ejabberd_odbc:escape(integer_to_list(TimeStamp)),
|
||||||
State = ejabberd_odbc:escape(Status),
|
State = ejabberd_odbc:escape(Status),
|
||||||
["delete from last where username='", Username, "';"
|
["delete from last where host='", ServerS, "' and username='", Username, "';\n"
|
||||||
"insert into last(username, seconds, state) "
|
"insert into last(username, seconds, state) "
|
||||||
"values ('", Username, "', '", Seconds, "', '", State, "');"];
|
"values ('", Username, "', '", Seconds, "', '", State, "');\n"];
|
||||||
(_Host, _R) ->
|
(_Host, _R) ->
|
||||||
[]
|
[]
|
||||||
end).
|
end).
|
||||||
@ -170,15 +181,15 @@ export_last(ServerS, Output) ->
|
|||||||
export_vcard(Server, Output) ->
|
export_vcard(Server, Output) ->
|
||||||
export_common(
|
export_common(
|
||||||
Server, vcard, Output,
|
Server, vcard, Output,
|
||||||
fun(Host, #vcard{us = {LUser, LServer},
|
fun(Host, #vcard{user_host = {LUser, LServer},
|
||||||
vcard = VCARD})
|
vcard = VCARD})
|
||||||
when LServer == Host ->
|
when LServer == Host ->
|
||||||
Username = ejabberd_odbc:escape(LUser),
|
Username = ejabberd_odbc:escape(LUser),
|
||||||
SVCARD = ejabberd_odbc:escape(
|
SVCARD = ejabberd_odbc:escape(
|
||||||
exmpp_xml:document_to_list(VCARD)),
|
exmpp_xml:document_to_list(VCARD)),
|
||||||
["delete from vcard where username='", Username, "';"
|
["delete from vcard where host='", Server,"' and username='", Username, "';\n"
|
||||||
"insert into vcard(username, vcard) "
|
"insert into vcard(host, username, vcard) "
|
||||||
"values ('", Username, "', '", SVCARD, "');"];
|
"values ('", Server, "', '", Username, "', '", SVCARD, "');\n"];
|
||||||
(_Host, _R) ->
|
(_Host, _R) ->
|
||||||
[]
|
[]
|
||||||
end).
|
end).
|
||||||
@ -227,7 +238,7 @@ export_vcard_search(Server, Output) ->
|
|||||||
SOrgUnit = ejabberd_odbc:escape(OrgUnit),
|
SOrgUnit = ejabberd_odbc:escape(OrgUnit),
|
||||||
SLOrgUnit = ejabberd_odbc:escape(LOrgUnit),
|
SLOrgUnit = ejabberd_odbc:escape(LOrgUnit),
|
||||||
|
|
||||||
["delete from vcard_search where lusername='", LUsername, "';"
|
["delete from vcard_search where host='", Server, "' and lusername='", LUsername, "';\n"
|
||||||
"insert into vcard_search("
|
"insert into vcard_search("
|
||||||
" username, lusername, fn, lfn, family, lfamily,"
|
" username, lusername, fn, lfn, family, lfamily,"
|
||||||
" given, lgiven, middle, lmiddle, nickname, lnickname,"
|
" given, lgiven, middle, lmiddle, nickname, lnickname,"
|
||||||
@ -245,7 +256,7 @@ export_vcard_search(Server, Output) ->
|
|||||||
" '", SLocality, "', '", SLLocality, "',"
|
" '", SLocality, "', '", SLLocality, "',"
|
||||||
" '", SEMail, "', '", SLEMail, "',"
|
" '", SEMail, "', '", SLEMail, "',"
|
||||||
" '", SOrgName, "', '", SLOrgName, "',"
|
" '", SOrgName, "', '", SLOrgName, "',"
|
||||||
" '", SOrgUnit, "', '", SLOrgUnit, "');"];
|
" '", SOrgUnit, "', '", SLOrgUnit, "');\n"];
|
||||||
(_Host, _R) ->
|
(_Host, _R) ->
|
||||||
[]
|
[]
|
||||||
end).
|
end).
|
||||||
@ -254,7 +265,7 @@ export_private_storage(ServerS, Output) ->
|
|||||||
Server = list_to_binary(ServerS),
|
Server = list_to_binary(ServerS),
|
||||||
export_common(
|
export_common(
|
||||||
Server, private_storage, Output,
|
Server, private_storage, Output,
|
||||||
fun(Host, #private_storage{usns = {LUser, LServer, XMLNS},
|
fun(Host, #private_storage{user_host_ns = {LUser, LServer, XMLNS},
|
||||||
xml = Data})
|
xml = Data})
|
||||||
when LServer == Host ->
|
when LServer == Host ->
|
||||||
Username = ejabberd_odbc:escape(LUser),
|
Username = ejabberd_odbc:escape(LUser),
|
||||||
@ -295,7 +306,7 @@ export_common(Server, Table, Output, ConvertFun) ->
|
|||||||
true ->
|
true ->
|
||||||
%% Execute full SQL transaction
|
%% Execute full SQL transaction
|
||||||
output(LServer, IO,
|
output(LServer, IO,
|
||||||
["begin;",
|
["begin;\n",
|
||||||
lists:reverse([SQL | SQLs]),
|
lists:reverse([SQL | SQLs]),
|
||||||
"commit"]),
|
"commit"]),
|
||||||
{0, []}
|
{0, []}
|
||||||
@ -304,7 +315,7 @@ export_common(Server, Table, Output, ConvertFun) ->
|
|||||||
end, {0, []}, Table),
|
end, {0, []}, Table),
|
||||||
%% Execute SQL transaction with remaining records
|
%% Execute SQL transaction with remaining records
|
||||||
output(LServer, IO,
|
output(LServer, IO,
|
||||||
["begin;",
|
["begin;\n",
|
||||||
lists:reverse(SQLs),
|
lists:reverse(SQLs),
|
||||||
"commit"])
|
"commit"])
|
||||||
end).
|
end).
|
||||||
@ -317,11 +328,11 @@ output(LServer, IO, SQL) ->
|
|||||||
file:write(IO, [SQL, $;, $\n])
|
file:write(IO, [SQL, $;, $\n])
|
||||||
end.
|
end.
|
||||||
|
|
||||||
record_to_string(#roster{usj = {User, _Server, {N, D, R} = _JID},
|
record_to_string(#rosteritem{user_host_jid = {User, _Server, {N, D, R} = _JID},
|
||||||
name = Name,
|
name = Name,
|
||||||
subscription = Subscription,
|
subscription = Subscription,
|
||||||
ask = Ask,
|
ask = Ask,
|
||||||
askmessage = AskMessage}) ->
|
askmessage = AskMessage}, ServerS) ->
|
||||||
Username = ejabberd_odbc:escape(User),
|
Username = ejabberd_odbc:escape(User),
|
||||||
SJID = ejabberd_odbc:escape(exmpp_jid:to_list(N, D, R)),
|
SJID = ejabberd_odbc:escape(exmpp_jid:to_list(N, D, R)),
|
||||||
Nick = ejabberd_odbc:escape(Name),
|
Nick = ejabberd_odbc:escape(Name),
|
||||||
@ -348,6 +359,7 @@ record_to_string(#roster{usj = {User, _Server, {N, D, R} = _JID},
|
|||||||
SAM
|
SAM
|
||||||
end,
|
end,
|
||||||
["("
|
["("
|
||||||
|
"'", ServerS, "',"
|
||||||
"'", Username, "',"
|
"'", Username, "',"
|
||||||
"'", SJID, "',"
|
"'", SJID, "',"
|
||||||
"'", Nick, "',"
|
"'", Nick, "',"
|
||||||
@ -356,11 +368,12 @@ record_to_string(#roster{usj = {User, _Server, {N, D, R} = _JID},
|
|||||||
"'", SAskMessage, "',"
|
"'", SAskMessage, "',"
|
||||||
"'N', '', 'item')"].
|
"'N', '', 'item')"].
|
||||||
|
|
||||||
groups_to_string(#roster{usj = {User, _Server, {N, D, R} = _JID},
|
group_to_string(#rostergroup{user_host_jid = {User, _Server, {N, D, R} = _JID},
|
||||||
groups = Groups}) ->
|
grp = Group}, ServerS) ->
|
||||||
Username = ejabberd_odbc:escape(User),
|
Username = ejabberd_odbc:escape(User),
|
||||||
SJID = ejabberd_odbc:escape(exmpp_jid:to_list(N, D, R)),
|
SJID = ejabberd_odbc:escape(exmpp_jid:to_list(N, D, R)),
|
||||||
[["("
|
["("
|
||||||
|
"'", ServerS, "',"
|
||||||
"'", Username, "',"
|
"'", Username, "',"
|
||||||
"'", SJID, "',"
|
"'", SJID, "',"
|
||||||
"'", ejabberd_odbc:escape(Group), "')"] || Group <- Groups].
|
"'", ejabberd_odbc:escape(Group), "')"].
|
||||||
|
@ -133,17 +133,19 @@ store_room(Host, Name, Opts) when is_binary(Host), is_binary(Name) ->
|
|||||||
{_, _} = A -> A;
|
{_, _} = A -> A;
|
||||||
A when is_atom(A) -> {A, ""}
|
A when is_atom(A) -> {A, ""}
|
||||||
end,
|
end,
|
||||||
|
{Username, Server, Resource} = JID,
|
||||||
gen_storage:write(
|
gen_storage:write(
|
||||||
Host,
|
Host,
|
||||||
#muc_room_affiliation{name_host = {Name, Host},
|
#muc_room_affiliation{name_host = {Name, Host},
|
||||||
jid = jlib:make_jid(JID),
|
jid = exmpp_jid:make(Username, Server, Resource),
|
||||||
affiliation = Affiliation,
|
affiliation = Affiliation,
|
||||||
reason = Reason})
|
reason = Reason})
|
||||||
end, Affiliations);
|
end, Affiliations);
|
||||||
({Opt, Val}) ->
|
({Opt, Val}) ->
|
||||||
ValS = if
|
ValS = if
|
||||||
is_integer(Val) -> integer_to_list(Val);
|
is_integer(Val) -> integer_to_list(Val);
|
||||||
is_list(Val);
|
is_binary(Val) -> binary_to_list(Val);
|
||||||
|
is_list(Val) -> Val;
|
||||||
is_atom(Val) -> Val
|
is_atom(Val) -> Val
|
||||||
end,
|
end,
|
||||||
gen_storage:write(Host,
|
gen_storage:write(Host,
|
||||||
@ -194,7 +196,7 @@ restore_room_internal(Host, Name) ->
|
|||||||
"" -> Affiliation;
|
"" -> Affiliation;
|
||||||
_ -> {Affiliation, Reason}
|
_ -> {Affiliation, Reason}
|
||||||
end,
|
end,
|
||||||
{jlib:jid_tolower(JID), A}
|
{jlib:short_prepd_jid(JID), A}
|
||||||
end, RoomAffiliations),
|
end, RoomAffiliations),
|
||||||
[{affiliations, Affiliations} | Opts].
|
[{affiliations, Affiliations} | Opts].
|
||||||
|
|
||||||
@ -646,7 +648,7 @@ load_permanent_rooms(Host, ServerHost, Access, HistorySize, RoomShaper) ->
|
|||||||
start_new_room(Host, ServerHost, Access, Room,
|
start_new_room(Host, ServerHost, Access, Room,
|
||||||
HistorySize, RoomShaper, From,
|
HistorySize, RoomShaper, From,
|
||||||
Nick, DefRoomOpts) ->
|
Nick, DefRoomOpts) ->
|
||||||
case gen_storage:read(Host, {muc_room_opt, {Room, Host}}) of
|
case gen_storage:dirty_read(Host, {muc_room_opt, {Room, Host}}) of
|
||||||
[] ->
|
[] ->
|
||||||
?DEBUG("MUC: open new room '~s'~n", [Room]),
|
?DEBUG("MUC: open new room '~s'~n", [Room]),
|
||||||
mod_muc_room:start(Host, ServerHost, Access,
|
mod_muc_room:start(Host, ServerHost, Access,
|
||||||
@ -711,7 +713,7 @@ iq_disco_items(Host, From, Lang, none) when is_binary(Host) ->
|
|||||||
flush(),
|
flush(),
|
||||||
{true,
|
{true,
|
||||||
{xmlelement, "item",
|
{xmlelement, "item",
|
||||||
[{"jid", jlib:jid_to_string({Name, Host, ""})},
|
[{"jid", exmpp_jid:to_list(Name, Host, "")},
|
||||||
{"name", Desc}], []}};
|
{"name", Desc}], []}};
|
||||||
_ ->
|
_ ->
|
||||||
false
|
false
|
||||||
@ -735,7 +737,7 @@ iq_disco_items(Host, From, Lang, Rsm) ->
|
|||||||
_ ->
|
_ ->
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
end, get_vh_rooms_all_nodes(Host)).
|
end, Rooms) ++ RsmOut.
|
||||||
|
|
||||||
get_vh_rooms(Host, #rsm_in{max=M, direction=Direction, id=I, index=Index})->
|
get_vh_rooms(Host, #rsm_in{max=M, direction=Direction, id=I, index=Index})->
|
||||||
AllRooms = get_vh_rooms_all_nodes(Host),
|
AllRooms = get_vh_rooms_all_nodes(Host),
|
||||||
|
Loading…
Reference in New Issue
Block a user