25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-26 16:26:24 +01:00

Fix core files

This commit is contained in:
Badlop 2010-07-22 18:48:23 +02:00
parent 13fad04d14
commit 58bed2cbff
8 changed files with 200 additions and 111 deletions

View File

@ -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"};

View File

@ -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,

View File

@ -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}).

View File

@ -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.

View File

@ -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.

View File

@ -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 ->

View File

@ -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), "')"].

View File

@ -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),