aboutsummaryrefslogtreecommitdiff
path: root/src/mod_vcard.erl
diff options
context:
space:
mode:
authorBadlop <badlop@process-one.net>2013-03-14 10:33:02 +0100
committerBadlop <badlop@process-one.net>2013-03-14 10:33:02 +0100
commit9deb294328bb3f9eb6bd2c0e7cd500732e9b5830 (patch)
tree7e1066c130250627ee0abab44a135f583a28d07f /src/mod_vcard.erl
parentlist_to_integer/2 only works in OTP R14 and newer (diff)
Accumulated patch to binarize and indent code
Diffstat (limited to '')
-rw-r--r--src/mod_vcard.erl1628
1 files changed, 810 insertions, 818 deletions
diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl
index 3b70fe21f..901098398 100644
--- a/src/mod_vcard.erl
+++ b/src/mod_vcard.erl
@@ -25,644 +25,668 @@
%%%----------------------------------------------------------------------
-module(mod_vcard).
+
-author('alexey@process-one.net').
-behaviour(gen_mod).
--export([start/2, init/3, stop/1,
- get_sm_features/5,
- process_local_iq/3,
- process_sm_iq/3,
- reindex_vcards/0,
- remove_user/2]).
+-export([start/2, init/3, stop/1, get_sm_features/5,
+ process_local_iq/3, process_sm_iq/3, reindex_vcards/0,
+ remove_user/2, export/1]).
-include("ejabberd.hrl").
--include("jlib.hrl").
+-include("jlib.hrl").
-define(JUD_MATCHES, 30).
--record(vcard_search, {us,
- user, luser,
- fn, lfn,
- family, lfamily,
- given, lgiven,
- middle, lmiddle,
- nickname, lnickname,
- bday, lbday,
- ctry, lctry,
- locality, llocality,
- email, lemail,
- orgname, lorgname,
- orgunit, lorgunit
- }).
--record(vcard, {us, vcard}).
+-record(vcard_search,
+ {us, user, luser, fn, lfn, family, lfamily, given,
+ lgiven, middle, lmiddle, nickname, lnickname, bday,
+ lbday, ctry, lctry, locality, llocality, email, lemail,
+ orgname, lorgname, orgunit, lorgunit}).
+
+-record(vcard, {us = {<<"">>, <<"">>} :: {binary(), binary()},
+ vcard = #xmlel{} :: xmlel()}).
-define(PROCNAME, ejabberd_mod_vcard).
start(Host, Opts) ->
case gen_mod:db_type(Opts) of
- mnesia ->
- mnesia:create_table(vcard,
- [{disc_only_copies, [node()]},
- {attributes,
- record_info(fields, vcard)}]),
- mnesia:create_table(vcard_search,
- [{disc_copies, [node()]},
- {attributes,
- record_info(fields, vcard_search)}]),
- update_tables(),
- mnesia:add_table_index(vcard_search, luser),
- mnesia:add_table_index(vcard_search, lfn),
- mnesia:add_table_index(vcard_search, lfamily),
- mnesia:add_table_index(vcard_search, lgiven),
- mnesia:add_table_index(vcard_search, lmiddle),
- mnesia:add_table_index(vcard_search, lnickname),
- mnesia:add_table_index(vcard_search, lbday),
- mnesia:add_table_index(vcard_search, lctry),
- mnesia:add_table_index(vcard_search, llocality),
- mnesia:add_table_index(vcard_search, lemail),
- mnesia:add_table_index(vcard_search, lorgname),
- mnesia:add_table_index(vcard_search, lorgunit);
- _ ->
- ok
+ mnesia ->
+ mnesia:create_table(vcard,
+ [{disc_only_copies, [node()]},
+ {attributes, record_info(fields, vcard)}]),
+ mnesia:create_table(vcard_search,
+ [{disc_copies, [node()]},
+ {attributes,
+ record_info(fields, vcard_search)}]),
+ update_tables(),
+ mnesia:add_table_index(vcard_search, luser),
+ mnesia:add_table_index(vcard_search, lfn),
+ mnesia:add_table_index(vcard_search, lfamily),
+ mnesia:add_table_index(vcard_search, lgiven),
+ mnesia:add_table_index(vcard_search, lmiddle),
+ mnesia:add_table_index(vcard_search, lnickname),
+ mnesia:add_table_index(vcard_search, lbday),
+ mnesia:add_table_index(vcard_search, lctry),
+ mnesia:add_table_index(vcard_search, llocality),
+ mnesia:add_table_index(vcard_search, lemail),
+ mnesia:add_table_index(vcard_search, lorgname),
+ mnesia:add_table_index(vcard_search, lorgunit);
+ _ -> ok
end,
- ejabberd_hooks:add(remove_user, Host,
- ?MODULE, remove_user, 50),
- IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD,
- ?MODULE, process_local_iq, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
- ?MODULE, process_sm_iq, IQDisc),
- ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
- MyHost = gen_mod:get_opt_host(Host, Opts, "vjud.@HOST@"),
- Search = gen_mod:get_opt(search, Opts, true),
+ ejabberd_hooks:add(remove_user, Host, ?MODULE,
+ remove_user, 50),
+ IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
+ one_queue),
+ gen_iq_handler:add_iq_handler(ejabberd_local, Host,
+ ?NS_VCARD, ?MODULE, process_local_iq, IQDisc),
+ gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
+ ?NS_VCARD, ?MODULE, process_sm_iq, IQDisc),
+ ejabberd_hooks:add(disco_sm_features, Host, ?MODULE,
+ get_sm_features, 50),
+ MyHost = gen_mod:get_opt_host(Host, Opts,
+ <<"vjud.@HOST@">>),
+ Search = gen_mod:get_opt(search, Opts,
+ fun(B) when is_boolean(B) -> B end,
+ true),
register(gen_mod:get_module_proc(Host, ?PROCNAME),
spawn(?MODULE, init, [MyHost, Host, Search])).
-
init(Host, ServerHost, Search) ->
case Search of
- false ->
- loop(Host, ServerHost);
- _ ->
- ejabberd_router:register_route(Host),
- loop(Host, ServerHost)
+ false -> loop(Host, ServerHost);
+ _ ->
+ ejabberd_router:register_route(Host),
+ loop(Host, ServerHost)
end.
loop(Host, ServerHost) ->
receive
- {route, From, To, Packet} ->
- case catch do_route(ServerHost, From, To, Packet) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p", [Reason]);
- _ ->
- ok
- end,
- loop(Host, ServerHost);
- stop ->
- ejabberd_router:unregister_route(Host),
- ok;
- _ ->
- loop(Host, ServerHost)
+ {route, From, To, Packet} ->
+ case catch do_route(ServerHost, From, To, Packet) of
+ {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]);
+ _ -> ok
+ end,
+ loop(Host, ServerHost);
+ stop -> ejabberd_router:unregister_route(Host), ok;
+ _ -> loop(Host, ServerHost)
end.
stop(Host) ->
- ejabberd_hooks:delete(remove_user, Host,
- ?MODULE, remove_user, 50),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD),
- ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
+ ejabberd_hooks:delete(remove_user, Host, ?MODULE,
+ remove_user, 50),
+ gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
+ ?NS_VCARD),
+ gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
+ ?NS_VCARD),
+ ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE,
+ get_sm_features, 50),
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
Proc ! stop,
{wait, Proc}.
-get_sm_features({error, _Error} = Acc, _From, _To, _Node, _Lang) ->
+get_sm_features({error, _Error} = Acc, _From, _To,
+ _Node, _Lang) ->
Acc;
-
get_sm_features(Acc, _From, _To, Node, _Lang) ->
case Node of
- [] ->
- case Acc of
- {result, Features} ->
- {result, [?NS_DISCO_INFO, ?NS_VCARD | Features]};
- empty ->
- {result, [?NS_DISCO_INFO, ?NS_VCARD]}
- end;
- _ ->
- Acc
- end.
-
-process_local_iq(_From, _To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
- case Type of
- set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
- get ->
- IQ#iq{type = result,
- sub_el = [{xmlelement, "vCard",
- [{"xmlns", ?NS_VCARD}],
- [{xmlelement, "FN", [],
- [{xmlcdata, "ejabberd"}]},
- {xmlelement, "URL", [],
- [{xmlcdata, ?EJABBERD_URI}]},
- {xmlelement, "DESC", [],
- [{xmlcdata,
- translate:translate(
- Lang,
- "Erlang Jabber Server") ++
- "\nCopyright (c) 2002-2013 ProcessOne"}]},
- {xmlelement, "BDAY", [],
- [{xmlcdata, "2002-11-16"}]}
- ]}]}
+ <<"">> ->
+ case Acc of
+ {result, Features} ->
+ {result, [?NS_DISCO_INFO, ?NS_VCARD | Features]};
+ empty -> {result, [?NS_DISCO_INFO, ?NS_VCARD]}
+ end;
+ _ -> Acc
end.
+process_local_iq(_From, _To,
+ #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
+ case Type of
+ set ->
+ IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
+ get ->
+ IQ#iq{type = result,
+ sub_el =
+ [#xmlel{name = <<"vCard">>,
+ attrs = [{<<"xmlns">>, ?NS_VCARD}],
+ children =
+ [#xmlel{name = <<"FN">>, attrs = [],
+ children =
+ [{xmlcdata, <<"ejabberd">>}]},
+ #xmlel{name = <<"URL">>, attrs = [],
+ children = [{xmlcdata, ?EJABBERD_URI}]},
+ #xmlel{name = <<"DESC">>, attrs = [],
+ children =
+ [{xmlcdata,
+ <<(translate:translate(Lang,
+ <<"Erlang Jabber Server">>))/binary,
+ "\nCopyright (c) 2002-2013 ProcessOne">>}]},
+ #xmlel{name = <<"BDAY">>, attrs = [],
+ children =
+ [{xmlcdata, <<"2002-11-16">>}]}]}]}
+ end.
-process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
+process_sm_iq(From, To,
+ #iq{type = Type, sub_el = SubEl} = IQ) ->
case Type of
- set ->
- #jid{user = User, lserver = LServer} = From,
- case lists:member(LServer, ?MYHOSTS) of
- true ->
- set_vcard(User, LServer, SubEl),
- IQ#iq{type = result, sub_el = []};
- false ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
- end;
- get ->
- #jid{luser = LUser, lserver = LServer} = To,
- case get_vcard(LUser, LServer) of
- error ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]};
- Els ->
- IQ#iq{type = result, sub_el = Els}
- end
+ set ->
+ #jid{user = User, lserver = LServer} = From,
+ case lists:member(LServer, ?MYHOSTS) of
+ true ->
+ set_vcard(User, LServer, SubEl),
+ IQ#iq{type = result, sub_el = []};
+ false ->
+ IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
+ end;
+ get ->
+ #jid{luser = LUser, lserver = LServer} = To,
+ case get_vcard(LUser, LServer) of
+ error ->
+ IQ#iq{type = error,
+ sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]};
+ Els -> IQ#iq{type = result, sub_el = Els}
+ end
end.
get_vcard(LUser, LServer) ->
- get_vcard(LUser, LServer, gen_mod:db_type(LServer, ?MODULE)).
+ get_vcard(LUser, LServer,
+ gen_mod:db_type(LServer, ?MODULE)).
get_vcard(LUser, LServer, mnesia) ->
US = {LUser, LServer},
- F = fun() ->
- mnesia:read({vcard, US})
- end,
+ F = fun () -> mnesia:read({vcard, US}) end,
case mnesia:transaction(F) of
- {atomic, Rs} ->
- lists:map(fun(R) ->
- R#vcard.vcard
- end, Rs);
- {aborted, _Reason} ->
- error
+ {atomic, Rs} ->
+ lists:map(fun (R) -> R#vcard.vcard end, Rs);
+ {aborted, _Reason} -> error
end;
get_vcard(LUser, LServer, odbc) ->
Username = ejabberd_odbc:escape(LUser),
case catch odbc_queries:get_vcard(LServer, Username) of
- {selected, ["vcard"], [{SVCARD}]} ->
- case xml_stream:parse_element(SVCARD) of
- {error, _Reason} ->
- error;
- VCARD ->
- [VCARD]
- end;
- {selected, ["vcard"], []} ->
- [];
- _ ->
- error
+ {selected, [<<"vcard">>], [[SVCARD]]} ->
+ case xml_stream:parse_element(SVCARD) of
+ {error, _Reason} -> error;
+ VCARD -> [VCARD]
+ end;
+ {selected, [<<"vcard">>], []} -> [];
+ _ -> error
end.
set_vcard(User, LServer, VCARD) ->
- FN = xml:get_path_s(VCARD, [{elem, "FN"}, cdata]),
- Family = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "FAMILY"}, cdata]),
- Given = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "GIVEN"}, cdata]),
- Middle = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "MIDDLE"}, cdata]),
- Nickname = xml:get_path_s(VCARD, [{elem, "NICKNAME"}, cdata]),
- BDay = xml:get_path_s(VCARD, [{elem, "BDAY"}, cdata]),
- CTRY = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "CTRY"}, cdata]),
- Locality = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "LOCALITY"},cdata]),
- EMail1 = xml:get_path_s(VCARD, [{elem, "EMAIL"}, {elem, "USERID"},cdata]),
- EMail2 = xml:get_path_s(VCARD, [{elem, "EMAIL"}, cdata]),
- OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]),
- OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]),
+ FN = xml:get_path_s(VCARD, [{elem, <<"FN">>}, cdata]),
+ Family = xml:get_path_s(VCARD,
+ [{elem, <<"N">>}, {elem, <<"FAMILY">>}, cdata]),
+ Given = xml:get_path_s(VCARD,
+ [{elem, <<"N">>}, {elem, <<"GIVEN">>}, cdata]),
+ Middle = xml:get_path_s(VCARD,
+ [{elem, <<"N">>}, {elem, <<"MIDDLE">>}, cdata]),
+ Nickname = xml:get_path_s(VCARD,
+ [{elem, <<"NICKNAME">>}, cdata]),
+ BDay = xml:get_path_s(VCARD,
+ [{elem, <<"BDAY">>}, cdata]),
+ CTRY = xml:get_path_s(VCARD,
+ [{elem, <<"ADR">>}, {elem, <<"CTRY">>}, cdata]),
+ Locality = xml:get_path_s(VCARD,
+ [{elem, <<"ADR">>}, {elem, <<"LOCALITY">>},
+ cdata]),
+ EMail1 = xml:get_path_s(VCARD,
+ [{elem, <<"EMAIL">>}, {elem, <<"USERID">>}, cdata]),
+ EMail2 = xml:get_path_s(VCARD,
+ [{elem, <<"EMAIL">>}, cdata]),
+ OrgName = xml:get_path_s(VCARD,
+ [{elem, <<"ORG">>}, {elem, <<"ORGNAME">>}, cdata]),
+ OrgUnit = xml:get_path_s(VCARD,
+ [{elem, <<"ORG">>}, {elem, <<"ORGUNIT">>}, cdata]),
EMail = case EMail1 of
- "" ->
- EMail2;
- _ ->
- EMail1
+ <<"">> -> EMail2;
+ _ -> EMail1
end,
-
- LUser = jlib:nodeprep(User),
- LFN = string2lower(FN),
- LFamily = string2lower(Family),
- LGiven = string2lower(Given),
- LMiddle = string2lower(Middle),
+ LUser = jlib:nodeprep(User),
+ LFN = string2lower(FN),
+ LFamily = string2lower(Family),
+ LGiven = string2lower(Given),
+ LMiddle = string2lower(Middle),
LNickname = string2lower(Nickname),
- LBDay = string2lower(BDay),
- LCTRY = string2lower(CTRY),
+ LBDay = string2lower(BDay),
+ LCTRY = string2lower(CTRY),
LLocality = string2lower(Locality),
- LEMail = string2lower(EMail),
- LOrgName = string2lower(OrgName),
- LOrgUnit = string2lower(OrgUnit),
-
- if
- (LUser == error) or
- (LFN == error) or
- (LFamily == error) or
- (LGiven == error) or
- (LMiddle == error) or
- (LNickname == error) or
- (LBDay == error) or
- (LCTRY == error) or
- (LLocality == error) or
- (LEMail == error) or
- (LOrgName == error) or
- (LOrgUnit == error) ->
- {error, badarg};
- true ->
- case gen_mod:db_type(LServer, ?MODULE) of
- mnesia ->
- US = {LUser, LServer},
- F = fun() ->
- mnesia:write(#vcard{us = US, vcard = VCARD}),
- mnesia:write(
- #vcard_search{us = US,
- user = {User, LServer},
- luser = LUser,
- fn = FN, lfn = LFN,
- family = Family, lfamily = LFamily,
- given = Given, lgiven = LGiven,
- middle = Middle, lmiddle = LMiddle,
- nickname = Nickname, lnickname = LNickname,
- bday = BDay, lbday = LBDay,
- ctry = CTRY, lctry = LCTRY,
- locality = Locality, llocality = LLocality,
- email = EMail, lemail = LEMail,
- orgname = OrgName, lorgname = LOrgName,
- orgunit = OrgUnit, lorgunit = LOrgUnit
- })
- end,
- mnesia:transaction(F);
- odbc ->
- Username = ejabberd_odbc:escape(User),
- LUsername = ejabberd_odbc:escape(LUser),
- SVCARD = ejabberd_odbc:escape(
- xml:element_to_binary(VCARD)),
-
- SFN = ejabberd_odbc:escape(FN),
- SLFN = ejabberd_odbc:escape(LFN),
- SFamily = ejabberd_odbc:escape(Family),
- SLFamily = ejabberd_odbc:escape(LFamily),
- SGiven = ejabberd_odbc:escape(Given),
- SLGiven = ejabberd_odbc:escape(LGiven),
- SMiddle = ejabberd_odbc:escape(Middle),
- SLMiddle = ejabberd_odbc:escape(LMiddle),
- SNickname = ejabberd_odbc:escape(Nickname),
- SLNickname = ejabberd_odbc:escape(LNickname),
- SBDay = ejabberd_odbc:escape(BDay),
- SLBDay = ejabberd_odbc:escape(LBDay),
- SCTRY = ejabberd_odbc:escape(CTRY),
- SLCTRY = ejabberd_odbc:escape(LCTRY),
- SLocality = ejabberd_odbc:escape(Locality),
- SLLocality = ejabberd_odbc:escape(LLocality),
- SEMail = ejabberd_odbc:escape(EMail),
- SLEMail = ejabberd_odbc:escape(LEMail),
- SOrgName = ejabberd_odbc:escape(OrgName),
- SLOrgName = ejabberd_odbc:escape(LOrgName),
- SOrgUnit = ejabberd_odbc:escape(OrgUnit),
- SLOrgUnit = ejabberd_odbc:escape(LOrgUnit),
-
- odbc_queries:set_vcard(LServer, LUsername, SBDay, SCTRY, SEMail,
- SFN, SFamily, SGiven, SLBDay, SLCTRY,
- SLEMail, SLFN, SLFamily, SLGiven,
- SLLocality, SLMiddle, SLNickname,
- SLOrgName, SLOrgUnit, SLocality,
- SMiddle, SNickname, SOrgName,
- SOrgUnit, SVCARD, Username)
- end,
- ejabberd_hooks:run(vcard_set, LServer, [LUser, LServer, VCARD])
+ LEMail = string2lower(EMail),
+ LOrgName = string2lower(OrgName),
+ LOrgUnit = string2lower(OrgUnit),
+ if (LUser == error) ->
+ {error, badarg};
+ true ->
+ case gen_mod:db_type(LServer, ?MODULE) of
+ mnesia ->
+ US = {LUser, LServer},
+ F = fun () ->
+ mnesia:write(#vcard{us = US, vcard = VCARD}),
+ mnesia:write(#vcard_search{us = US,
+ user = {User, LServer},
+ luser = LUser, fn = FN,
+ lfn = LFN,
+ family = Family,
+ lfamily = LFamily,
+ given = Given,
+ lgiven = LGiven,
+ middle = Middle,
+ lmiddle = LMiddle,
+ nickname = Nickname,
+ lnickname = LNickname,
+ bday = BDay,
+ lbday = LBDay,
+ ctry = CTRY,
+ lctry = LCTRY,
+ locality = Locality,
+ llocality = LLocality,
+ email = EMail,
+ lemail = LEMail,
+ orgname = OrgName,
+ lorgname = LOrgName,
+ orgunit = OrgUnit,
+ lorgunit = LOrgUnit})
+ end,
+ mnesia:transaction(F);
+ odbc ->
+ Username = ejabberd_odbc:escape(User),
+ LUsername = ejabberd_odbc:escape(LUser),
+ SVCARD =
+ ejabberd_odbc:escape(xml:element_to_binary(VCARD)),
+ SFN = ejabberd_odbc:escape(FN),
+ SLFN = ejabberd_odbc:escape(LFN),
+ SFamily = ejabberd_odbc:escape(Family),
+ SLFamily = ejabberd_odbc:escape(LFamily),
+ SGiven = ejabberd_odbc:escape(Given),
+ SLGiven = ejabberd_odbc:escape(LGiven),
+ SMiddle = ejabberd_odbc:escape(Middle),
+ SLMiddle = ejabberd_odbc:escape(LMiddle),
+ SNickname = ejabberd_odbc:escape(Nickname),
+ SLNickname = ejabberd_odbc:escape(LNickname),
+ SBDay = ejabberd_odbc:escape(BDay),
+ SLBDay = ejabberd_odbc:escape(LBDay),
+ SCTRY = ejabberd_odbc:escape(CTRY),
+ SLCTRY = ejabberd_odbc:escape(LCTRY),
+ SLocality = ejabberd_odbc:escape(Locality),
+ SLLocality = ejabberd_odbc:escape(LLocality),
+ SEMail = ejabberd_odbc:escape(EMail),
+ SLEMail = ejabberd_odbc:escape(LEMail),
+ SOrgName = ejabberd_odbc:escape(OrgName),
+ SLOrgName = ejabberd_odbc:escape(LOrgName),
+ SOrgUnit = ejabberd_odbc:escape(OrgUnit),
+ SLOrgUnit = ejabberd_odbc:escape(LOrgUnit),
+ odbc_queries:set_vcard(LServer, LUsername, SBDay, SCTRY,
+ SEMail, SFN, SFamily, SGiven, SLBDay,
+ SLCTRY, SLEMail, SLFN, SLFamily,
+ SLGiven, SLLocality, SLMiddle,
+ SLNickname, SLOrgName, SLOrgUnit,
+ SLocality, SMiddle, SNickname, SOrgName,
+ SOrgUnit, SVCARD, Username)
+ end,
+ ejabberd_hooks:run(vcard_set, LServer,
+ [LUser, LServer, VCARD])
end.
string2lower(String) ->
case stringprep:tolower(String) of
- Lower when is_list(Lower) -> Lower;
- error -> string:to_lower(String)
+ Lower when is_binary(Lower) -> Lower;
+ error -> str:to_lower(String)
end.
-define(TLFIELD(Type, Label, Var),
- {xmlelement, "field", [{"type", Type},
- {"label", translate:translate(Lang, Label)},
- {"var", Var}], []}).
-
+ #xmlel{name = <<"field">>,
+ attrs =
+ [{<<"type">>, Type},
+ {<<"label">>, translate:translate(Lang, Label)},
+ {<<"var">>, Var}],
+ children = []}).
-define(FORM(JID),
- [{xmlelement, "instructions", [],
- [{xmlcdata, translate:translate(Lang, "You need an x:data capable client to search")}]},
- {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}],
- [{xmlelement, "title", [],
- [{xmlcdata, translate:translate(Lang, "Search users in ") ++
- jlib:jid_to_string(JID)}]},
- {xmlelement, "instructions", [],
- [{xmlcdata, translate:translate(Lang, "Fill in the form to search "
- "for any matching Jabber User "
- "(Add * to the end of field to "
- "match substring)")}]},
- ?TLFIELD("text-single", "User", "user"),
- ?TLFIELD("text-single", "Full Name", "fn"),
- ?TLFIELD("text-single", "Name", "first"),
- ?TLFIELD("text-single", "Middle Name", "middle"),
- ?TLFIELD("text-single", "Family Name", "last"),
- ?TLFIELD("text-single", "Nickname", "nick"),
- ?TLFIELD("text-single", "Birthday", "bday"),
- ?TLFIELD("text-single", "Country", "ctry"),
- ?TLFIELD("text-single", "City", "locality"),
- ?TLFIELD("text-single", "Email", "email"),
- ?TLFIELD("text-single", "Organization Name", "orgname"),
- ?TLFIELD("text-single", "Organization Unit", "orgunit")
- ]}]).
-
-
-
+ [#xmlel{name = <<"instructions">>, attrs = [],
+ children =
+ [{xmlcdata,
+ translate:translate(Lang,
+ <<"You need an x:data capable client to "
+ "search">>)}]},
+ #xmlel{name = <<"x">>,
+ attrs =
+ [{<<"xmlns">>, ?NS_XDATA}, {<<"type">>, <<"form">>}],
+ children =
+ [#xmlel{name = <<"title">>, attrs = [],
+ children =
+ [{xmlcdata,
+ <<(translate:translate(Lang,
+ <<"Search users in ">>))/binary,
+ (jlib:jid_to_string(JID))/binary>>}]},
+ #xmlel{name = <<"instructions">>, attrs = [],
+ children =
+ [{xmlcdata,
+ translate:translate(Lang,
+ <<"Fill in the form to search for any matching "
+ "Jabber User (Add * to the end of field "
+ "to match substring)">>)}]},
+ ?TLFIELD(<<"text-single">>, <<"User">>, <<"user">>),
+ ?TLFIELD(<<"text-single">>, <<"Full Name">>, <<"fn">>),
+ ?TLFIELD(<<"text-single">>, <<"Name">>, <<"first">>),
+ ?TLFIELD(<<"text-single">>, <<"Middle Name">>,
+ <<"middle">>),
+ ?TLFIELD(<<"text-single">>, <<"Family Name">>,
+ <<"last">>),
+ ?TLFIELD(<<"text-single">>, <<"Nickname">>, <<"nick">>),
+ ?TLFIELD(<<"text-single">>, <<"Birthday">>, <<"bday">>),
+ ?TLFIELD(<<"text-single">>, <<"Country">>, <<"ctry">>),
+ ?TLFIELD(<<"text-single">>, <<"City">>, <<"locality">>),
+ ?TLFIELD(<<"text-single">>, <<"Email">>, <<"email">>),
+ ?TLFIELD(<<"text-single">>, <<"Organization Name">>,
+ <<"orgname">>),
+ ?TLFIELD(<<"text-single">>, <<"Organization Unit">>,
+ <<"orgunit">>)]}]).
do_route(ServerHost, From, To, Packet) ->
#jid{user = User, resource = Resource} = To,
- if
- (User /= "") or (Resource /= "") ->
- Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE),
- ejabberd_router:route(To, From, Err);
- true ->
- IQ = jlib:iq_query_info(Packet),
- case IQ of
- #iq{type = Type, xmlns = ?NS_SEARCH, lang = Lang, sub_el = SubEl} ->
- case Type of
- set ->
- XDataEl = find_xdata_el(SubEl),
- case XDataEl of
- false ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_BAD_REQUEST),
- ejabberd_router:route(To, From, Err);
- _ ->
- XData = jlib:parse_xdata_submit(XDataEl),
- case XData of
- invalid ->
- Err = jlib:make_error_reply(
- Packet,
- ?ERR_BAD_REQUEST),
- ejabberd_router:route(To, From,
- Err);
- _ ->
- ResIQ =
- IQ#iq{
- type = result,
- sub_el =
- [{xmlelement,
- "query",
- [{"xmlns", ?NS_SEARCH}],
- [{xmlelement, "x",
- [{"xmlns", ?NS_XDATA},
- {"type", "result"}],
- search_result(Lang, To, ServerHost, XData)
- }]}]},
- ejabberd_router:route(
- To, From, jlib:iq_to_xml(ResIQ))
- end
- end;
- get ->
- ResIQ = IQ#iq{type = result,
- sub_el = [{xmlelement,
- "query",
- [{"xmlns", ?NS_SEARCH}],
- ?FORM(To)
- }]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ))
- end;
- #iq{type = Type, xmlns = ?NS_DISCO_INFO, lang = Lang} ->
- case Type of
- set ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_NOT_ALLOWED),
- ejabberd_router:route(To, From, Err);
- get ->
- Info = ejabberd_hooks:run_fold(
- disco_info, ServerHost, [],
- [ServerHost, ?MODULE, "", ""]),
- ResIQ =
- IQ#iq{type = result,
- sub_el = [{xmlelement,
- "query",
- [{"xmlns", ?NS_DISCO_INFO}],
- [{xmlelement, "identity",
- [{"category", "directory"},
- {"type", "user"},
- {"name",
- translate:translate(Lang, "vCard User Search")}],
- []},
- {xmlelement, "feature",
- [{"var", ?NS_DISCO_INFO}], []},
- {xmlelement, "feature",
- [{"var", ?NS_SEARCH}], []},
- {xmlelement, "feature",
- [{"var", ?NS_VCARD}], []}
- ] ++ Info
- }]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ))
- end;
- #iq{type = Type, xmlns = ?NS_DISCO_ITEMS} ->
- case Type of
- set ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_NOT_ALLOWED),
- ejabberd_router:route(To, From, Err);
- get ->
- ResIQ =
- IQ#iq{type = result,
- sub_el = [{xmlelement,
- "query",
- [{"xmlns", ?NS_DISCO_ITEMS}],
- []}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ))
- end;
- #iq{type = get, xmlns = ?NS_VCARD, lang = Lang} ->
- ResIQ =
- IQ#iq{type = result,
- sub_el = [{xmlelement,
- "vCard",
- [{"xmlns", ?NS_VCARD}],
- iq_get_vcard(Lang)}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ));
- _ ->
- Err = jlib:make_error_reply(Packet,
- ?ERR_SERVICE_UNAVAILABLE),
- ejabberd_router:route(To, From, Err)
- end
+ if (User /= <<"">>) or (Resource /= <<"">>) ->
+ Err = jlib:make_error_reply(Packet,
+ ?ERR_SERVICE_UNAVAILABLE),
+ ejabberd_router:route(To, From, Err);
+ true ->
+ IQ = jlib:iq_query_info(Packet),
+ case IQ of
+ #iq{type = Type, xmlns = ?NS_SEARCH, lang = Lang,
+ sub_el = SubEl} ->
+ case Type of
+ set ->
+ XDataEl = find_xdata_el(SubEl),
+ case XDataEl of
+ false ->
+ Err = jlib:make_error_reply(Packet,
+ ?ERR_BAD_REQUEST),
+ ejabberd_router:route(To, From, Err);
+ _ ->
+ XData = jlib:parse_xdata_submit(XDataEl),
+ case XData of
+ invalid ->
+ Err = jlib:make_error_reply(Packet,
+ ?ERR_BAD_REQUEST),
+ ejabberd_router:route(To, From, Err);
+ _ ->
+ ResIQ = IQ#iq{type = result,
+ sub_el =
+ [#xmlel{name = <<"query">>,
+ attrs =
+ [{<<"xmlns">>,
+ ?NS_SEARCH}],
+ children =
+ [#xmlel{name =
+ <<"x">>,
+ attrs =
+ [{<<"xmlns">>,
+ ?NS_XDATA},
+ {<<"type">>,
+ <<"result">>}],
+ children
+ =
+ search_result(Lang,
+ To,
+ ServerHost,
+ XData)}]}]},
+ ejabberd_router:route(To, From,
+ jlib:iq_to_xml(ResIQ))
+ end
+ end;
+ get ->
+ ResIQ = IQ#iq{type = result,
+ sub_el =
+ [#xmlel{name = <<"query">>,
+ attrs =
+ [{<<"xmlns">>,
+ ?NS_SEARCH}],
+ children = ?FORM(To)}]},
+ ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ))
+ end;
+ #iq{type = Type, xmlns = ?NS_DISCO_INFO, lang = Lang} ->
+ case Type of
+ set ->
+ Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
+ ejabberd_router:route(To, From, Err);
+ get ->
+ Info = ejabberd_hooks:run_fold(disco_info, ServerHost,
+ [],
+ [ServerHost, ?MODULE,
+ <<"">>, <<"">>]),
+ ResIQ = IQ#iq{type = result,
+ sub_el =
+ [#xmlel{name = <<"query">>,
+ attrs =
+ [{<<"xmlns">>,
+ ?NS_DISCO_INFO}],
+ children =
+ [#xmlel{name =
+ <<"identity">>,
+ attrs =
+ [{<<"category">>,
+ <<"directory">>},
+ {<<"type">>,
+ <<"user">>},
+ {<<"name">>,
+ translate:translate(Lang,
+ <<"vCard User Search">>)}],
+ children = []},
+ #xmlel{name =
+ <<"feature">>,
+ attrs =
+ [{<<"var">>,
+ ?NS_DISCO_INFO}],
+ children = []},
+ #xmlel{name =
+ <<"feature">>,
+ attrs =
+ [{<<"var">>,
+ ?NS_SEARCH}],
+ children = []},
+ #xmlel{name =
+ <<"feature">>,
+ attrs =
+ [{<<"var">>,
+ ?NS_VCARD}],
+ children = []}]
+ ++ Info}]},
+ ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ))
+ end;
+ #iq{type = Type, xmlns = ?NS_DISCO_ITEMS} ->
+ case Type of
+ set ->
+ Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
+ ejabberd_router:route(To, From, Err);
+ get ->
+ ResIQ = IQ#iq{type = result,
+ sub_el =
+ [#xmlel{name = <<"query">>,
+ attrs =
+ [{<<"xmlns">>,
+ ?NS_DISCO_ITEMS}],
+ children = []}]},
+ ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ))
+ end;
+ #iq{type = get, xmlns = ?NS_VCARD, lang = Lang} ->
+ ResIQ = IQ#iq{type = result,
+ sub_el =
+ [#xmlel{name = <<"vCard">>,
+ attrs = [{<<"xmlns">>, ?NS_VCARD}],
+ children = iq_get_vcard(Lang)}]},
+ ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ));
+ _ ->
+ Err = jlib:make_error_reply(Packet,
+ ?ERR_SERVICE_UNAVAILABLE),
+ ejabberd_router:route(To, From, Err)
+ end
end.
iq_get_vcard(Lang) ->
- [{xmlelement, "FN", [],
- [{xmlcdata, "ejabberd/mod_vcard"}]},
- {xmlelement, "URL", [],
- [{xmlcdata, ?EJABBERD_URI}]},
- {xmlelement, "DESC", [],
- [{xmlcdata, translate:translate(
- Lang,
- "ejabberd vCard module") ++
- "\nCopyright (c) 2003-2013 ProcessOne"}]}].
-
-find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) ->
+ [#xmlel{name = <<"FN">>, attrs = [],
+ children = [{xmlcdata, <<"ejabberd/mod_vcard">>}]},
+ #xmlel{name = <<"URL">>, attrs = [],
+ children = [{xmlcdata, ?EJABBERD_URI}]},
+ #xmlel{name = <<"DESC">>, attrs = [],
+ children =
+ [{xmlcdata,
+ <<(translate:translate(Lang,
+ <<"ejabberd vCard module">>))/binary,
+ "\nCopyright (c) 2003-2013 ProcessOne">>}]}].
+
+find_xdata_el(#xmlel{children = SubEls}) ->
find_xdata_el1(SubEls).
-find_xdata_el1([]) ->
- false;
-find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) ->
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_XDATA ->
- {xmlelement, Name, Attrs, SubEls};
- _ ->
- find_xdata_el1(Els)
+find_xdata_el1([]) -> false;
+find_xdata_el1([#xmlel{name = Name, attrs = Attrs,
+ children = SubEls}
+ | Els]) ->
+ case xml:get_attr_s(<<"xmlns">>, Attrs) of
+ ?NS_XDATA ->
+ #xmlel{name = Name, attrs = Attrs, children = SubEls};
+ _ -> find_xdata_el1(Els)
end;
-find_xdata_el1([_ | Els]) ->
- find_xdata_el1(Els).
+find_xdata_el1([_ | Els]) -> find_xdata_el1(Els).
-define(LFIELD(Label, Var),
- {xmlelement, "field", [{"label", translate:translate(Lang, Label)},
- {"var", Var}], []}).
+ #xmlel{name = <<"field">>,
+ attrs =
+ [{<<"label">>, translate:translate(Lang, Label)},
+ {<<"var">>, Var}],
+ children = []}).
search_result(Lang, JID, ServerHost, Data) ->
- [{xmlelement, "title", [],
- [{xmlcdata, translate:translate(Lang, "Search Results for ") ++
- jlib:jid_to_string(JID)}]},
- {xmlelement, "reported", [],
- [?TLFIELD("text-single", "Jabber ID", "jid"),
- ?TLFIELD("text-single", "Full Name", "fn"),
- ?TLFIELD("text-single", "Name", "first"),
- ?TLFIELD("text-single", "Middle Name", "middle"),
- ?TLFIELD("text-single", "Family Name", "last"),
- ?TLFIELD("text-single", "Nickname", "nick"),
- ?TLFIELD("text-single", "Birthday", "bday"),
- ?TLFIELD("text-single", "Country", "ctry"),
- ?TLFIELD("text-single", "City", "locality"),
- ?TLFIELD("text-single", "Email", "email"),
- ?TLFIELD("text-single", "Organization Name", "orgname"),
- ?TLFIELD("text-single", "Organization Unit", "orgunit")
- ]}] ++ lists:map(fun(R) -> record_to_item(ServerHost, R) end,
- search(ServerHost, Data)).
+ [#xmlel{name = <<"title">>, attrs = [],
+ children =
+ [{xmlcdata,
+ <<(translate:translate(Lang,
+ <<"Search Results for ">>))/binary,
+ (jlib:jid_to_string(JID))/binary>>}]},
+ #xmlel{name = <<"reported">>, attrs = [],
+ children =
+ [?TLFIELD(<<"text-single">>, <<"Jabber ID">>,
+ <<"jid">>),
+ ?TLFIELD(<<"text-single">>, <<"Full Name">>, <<"fn">>),
+ ?TLFIELD(<<"text-single">>, <<"Name">>, <<"first">>),
+ ?TLFIELD(<<"text-single">>, <<"Middle Name">>,
+ <<"middle">>),
+ ?TLFIELD(<<"text-single">>, <<"Family Name">>,
+ <<"last">>),
+ ?TLFIELD(<<"text-single">>, <<"Nickname">>, <<"nick">>),
+ ?TLFIELD(<<"text-single">>, <<"Birthday">>, <<"bday">>),
+ ?TLFIELD(<<"text-single">>, <<"Country">>, <<"ctry">>),
+ ?TLFIELD(<<"text-single">>, <<"City">>, <<"locality">>),
+ ?TLFIELD(<<"text-single">>, <<"Email">>, <<"email">>),
+ ?TLFIELD(<<"text-single">>, <<"Organization Name">>,
+ <<"orgname">>),
+ ?TLFIELD(<<"text-single">>, <<"Organization Unit">>,
+ <<"orgunit">>)]}]
+ ++
+ lists:map(fun (R) -> record_to_item(ServerHost, R) end,
+ search(ServerHost, Data)).
-define(FIELD(Var, Val),
- {xmlelement, "field", [{"var", Var}],
- [{xmlelement, "value", [],
- [{xmlcdata, Val}]}]}).
-
-record_to_item(LServer, {Username, FN, Family, Given, Middle,
- Nickname, BDay, CTRY, Locality,
- EMail, OrgName, OrgUnit}) ->
- {xmlelement, "item", [],
- [
- ?FIELD("jid", Username ++ "@" ++ LServer),
- ?FIELD("fn", FN),
- ?FIELD("last", Family),
- ?FIELD("first", Given),
- ?FIELD("middle", Middle),
- ?FIELD("nick", Nickname),
- ?FIELD("bday", BDay),
- ?FIELD("ctry", CTRY),
- ?FIELD("locality", Locality),
- ?FIELD("email", EMail),
- ?FIELD("orgname", OrgName),
- ?FIELD("orgunit", OrgUnit)
- ]
- };
+ #xmlel{name = <<"field">>, attrs = [{<<"var">>, Var}],
+ children =
+ [#xmlel{name = <<"value">>, attrs = [],
+ children = [{xmlcdata, Val}]}]}).
+
+record_to_item(LServer,
+ [Username, FN, Family, Given, Middle, Nickname, BDay,
+ CTRY, Locality, EMail, OrgName, OrgUnit]) ->
+ #xmlel{name = <<"item">>, attrs = [],
+ children =
+ [?FIELD(<<"jid">>,
+ <<Username/binary, "@", LServer/binary>>),
+ ?FIELD(<<"fn">>, FN), ?FIELD(<<"last">>, Family),
+ ?FIELD(<<"first">>, Given),
+ ?FIELD(<<"middle">>, Middle),
+ ?FIELD(<<"nick">>, Nickname), ?FIELD(<<"bday">>, BDay),
+ ?FIELD(<<"ctry">>, CTRY),
+ ?FIELD(<<"locality">>, Locality),
+ ?FIELD(<<"email">>, EMail),
+ ?FIELD(<<"orgname">>, OrgName),
+ ?FIELD(<<"orgunit">>, OrgUnit)]};
record_to_item(_LServer, #vcard_search{} = R) ->
{User, Server} = R#vcard_search.user,
- {xmlelement, "item", [],
- [
- ?FIELD("jid", User ++ "@" ++ Server),
- ?FIELD("fn", R#vcard_search.fn),
- ?FIELD("last", R#vcard_search.family),
- ?FIELD("first", R#vcard_search.given),
- ?FIELD("middle", R#vcard_search.middle),
- ?FIELD("nick", R#vcard_search.nickname),
- ?FIELD("bday", R#vcard_search.bday),
- ?FIELD("ctry", R#vcard_search.ctry),
- ?FIELD("locality", R#vcard_search.locality),
- ?FIELD("email", R#vcard_search.email),
- ?FIELD("orgname", R#vcard_search.orgname),
- ?FIELD("orgunit", R#vcard_search.orgunit)
- ]
- }.
-
+ #xmlel{name = <<"item">>, attrs = [],
+ children =
+ [?FIELD(<<"jid">>, <<User/binary, "@", Server/binary>>),
+ ?FIELD(<<"fn">>, (R#vcard_search.fn)),
+ ?FIELD(<<"last">>, (R#vcard_search.family)),
+ ?FIELD(<<"first">>, (R#vcard_search.given)),
+ ?FIELD(<<"middle">>, (R#vcard_search.middle)),
+ ?FIELD(<<"nick">>, (R#vcard_search.nickname)),
+ ?FIELD(<<"bday">>, (R#vcard_search.bday)),
+ ?FIELD(<<"ctry">>, (R#vcard_search.ctry)),
+ ?FIELD(<<"locality">>, (R#vcard_search.locality)),
+ ?FIELD(<<"email">>, (R#vcard_search.email)),
+ ?FIELD(<<"orgname">>, (R#vcard_search.orgname)),
+ ?FIELD(<<"orgunit">>, (R#vcard_search.orgunit))]}.
search(LServer, Data) ->
- DBType = gen_mod:db_type(LServer, ?MODULE),
+ DBType = gen_mod:db_type(LServer, ?MODULE),
MatchSpec = make_matchspec(LServer, Data, DBType),
- AllowReturnAll = gen_mod:get_module_opt(LServer, ?MODULE,
- allow_return_all, false),
+ AllowReturnAll = gen_mod:get_module_opt(LServer, ?MODULE, allow_return_all,
+ fun(B) when is_boolean(B) -> B end,
+ false),
search(LServer, MatchSpec, AllowReturnAll, DBType).
search(LServer, MatchSpec, AllowReturnAll, mnesia) ->
- if
- (MatchSpec == #vcard_search{_ = '_'}) and (not AllowReturnAll) ->
- [];
- true ->
- case catch mnesia:dirty_select(vcard_search,
- [{MatchSpec, [], ['$_']}]) of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p", [Reason]),
- [];
- Rs ->
- case gen_mod:get_module_opt(LServer, ?MODULE,
- matches, ?JUD_MATCHES) of
- infinity ->
- Rs;
- Val when is_integer(Val) and (Val > 0) ->
- lists:sublist(Rs, Val);
- Val ->
- ?ERROR_MSG("Illegal option value ~p. "
- "Default value ~p substituted.",
- [{matches, Val}, ?JUD_MATCHES]),
- lists:sublist(Rs, ?JUD_MATCHES)
- end
- end
+ if (MatchSpec == #vcard_search{_ = '_'}) and
+ not AllowReturnAll ->
+ [];
+ true ->
+ case catch mnesia:dirty_select(vcard_search,
+ [{MatchSpec, [], ['$_']}])
+ of
+ {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]), [];
+ Rs ->
+ case gen_mod:get_module_opt(LServer, ?MODULE, matches,
+ fun(infinity) -> infinity;
+ (I) when is_integer(I),
+ I>0 ->
+ I
+ end, ?JUD_MATCHES) of
+ infinity ->
+ Rs;
+ Val ->
+ lists:sublist(Rs, Val)
+ end
+ end
end;
search(LServer, MatchSpec, AllowReturnAll, odbc) ->
- if
- (MatchSpec == "") and (not AllowReturnAll) ->
- [];
- true ->
- Limit = case gen_mod:get_module_opt(LServer, ?MODULE,
- matches, ?JUD_MATCHES) of
- infinity ->
- "";
- Val when is_integer(Val) and (Val > 0) ->
- [" LIMIT ", integer_to_list(Val)];
- Val ->
- ?ERROR_MSG("Illegal option value ~p. "
- "Default value ~p substituted.",
- [{matches, Val}, ?JUD_MATCHES]),
- [" LIMIT ", integer_to_list(?JUD_MATCHES)]
- end,
- case catch ejabberd_odbc:sql_query(
- LServer,
- ["select username, fn, family, given, middle, "
- " nickname, bday, ctry, locality, "
- " email, orgname, orgunit from vcard_search ",
- MatchSpec, Limit, ";"]) of
- {selected, ["username", "fn", "family", "given", "middle",
- "nickname", "bday", "ctry", "locality",
- "email", "orgname", "orgunit"],
- Rs} when is_list(Rs) ->
- Rs;
- Error ->
- ?ERROR_MSG("~p", [Error]),
- []
- end
+ if (MatchSpec == <<"">>) and not AllowReturnAll -> [];
+ true ->
+ Limit = case gen_mod:get_module_opt(LServer, ?MODULE, matches,
+ fun(infinity) -> infinity;
+ (I) when is_integer(I),
+ I>0 ->
+ I
+ end, ?JUD_MATCHES) of
+ infinity ->
+ <<"">>;
+ Val ->
+ [<<" LIMIT ">>,
+ jlib:integer_to_binary(Val)]
+ end,
+ case catch ejabberd_odbc:sql_query(LServer,
+ [<<"select username, fn, family, given, "
+ "middle, nickname, bday, ctry, "
+ "locality, email, orgname, orgunit "
+ "from vcard_search ">>,
+ MatchSpec, Limit, <<";">>])
+ of
+ {selected,
+ [<<"username">>, <<"fn">>, <<"family">>, <<"given">>,
+ <<"middle">>, <<"nickname">>, <<"bday">>, <<"ctry">>,
+ <<"locality">>, <<"email">>, <<"orgname">>,
+ <<"orgunit">>],
+ Rs}
+ when is_list(Rs) ->
+ Rs;
+ Error -> ?ERROR_MSG("~p", [Error]), []
+ end
end.
make_matchspec(LServer, Data, mnesia) ->
@@ -670,203 +694,197 @@ make_matchspec(LServer, Data, mnesia) ->
Match = filter_fields(Data, GlobMatch, LServer, mnesia),
Match;
make_matchspec(LServer, Data, odbc) ->
- filter_fields(Data, "", LServer, odbc).
+ filter_fields(Data, <<"">>, LServer, odbc).
-filter_fields([], Match, _LServer, mnesia) ->
- Match;
+filter_fields([], Match, _LServer, mnesia) -> Match;
filter_fields([], Match, _LServer, odbc) ->
case Match of
- "" ->
- "";
- _ ->
- [" where ", Match]
+ <<"">> -> <<"">>;
+ _ -> [<<" where ">>, Match]
end;
-filter_fields([{SVar, [Val]} | Ds], Match, LServer, mnesia)
- when is_list(Val) and (Val /= "") ->
+filter_fields([{SVar, [Val]} | Ds], Match, LServer,
+ mnesia)
+ when is_binary(Val) and (Val /= <<"">>) ->
LVal = string2lower(Val),
NewMatch = case SVar of
- "user" ->
- case gen_mod:get_module_opt(LServer, ?MODULE,
- search_all_hosts, true) of
- true ->
- Match#vcard_search{luser = make_val(LVal)};
- false ->
- Host = find_my_host(LServer),
- Match#vcard_search{us = {make_val(LVal), Host}}
- end;
- "fn" -> Match#vcard_search{lfn = make_val(LVal)};
- "last" -> Match#vcard_search{lfamily = make_val(LVal)};
- "first" -> Match#vcard_search{lgiven = make_val(LVal)};
- "middle" -> Match#vcard_search{lmiddle = make_val(LVal)};
- "nick" -> Match#vcard_search{lnickname = make_val(LVal)};
- "bday" -> Match#vcard_search{lbday = make_val(LVal)};
- "ctry" -> Match#vcard_search{lctry = make_val(LVal)};
- "locality" -> Match#vcard_search{llocality = make_val(LVal)};
- "email" -> Match#vcard_search{lemail = make_val(LVal)};
- "orgname" -> Match#vcard_search{lorgname = make_val(LVal)};
- "orgunit" -> Match#vcard_search{lorgunit = make_val(LVal)};
- _ -> Match
+ <<"user">> ->
+ case gen_mod:get_module_opt(LServer, ?MODULE,
+ search_all_hosts,
+ fun(B) when is_boolean(B) ->
+ B
+ end, true)
+ of
+ true -> Match#vcard_search{luser = make_val(LVal)};
+ false ->
+ Host = find_my_host(LServer),
+ Match#vcard_search{us = {make_val(LVal), Host}}
+ end;
+ <<"fn">> -> Match#vcard_search{lfn = make_val(LVal)};
+ <<"last">> ->
+ Match#vcard_search{lfamily = make_val(LVal)};
+ <<"first">> ->
+ Match#vcard_search{lgiven = make_val(LVal)};
+ <<"middle">> ->
+ Match#vcard_search{lmiddle = make_val(LVal)};
+ <<"nick">> ->
+ Match#vcard_search{lnickname = make_val(LVal)};
+ <<"bday">> ->
+ Match#vcard_search{lbday = make_val(LVal)};
+ <<"ctry">> ->
+ Match#vcard_search{lctry = make_val(LVal)};
+ <<"locality">> ->
+ Match#vcard_search{llocality = make_val(LVal)};
+ <<"email">> ->
+ Match#vcard_search{lemail = make_val(LVal)};
+ <<"orgname">> ->
+ Match#vcard_search{lorgname = make_val(LVal)};
+ <<"orgunit">> ->
+ Match#vcard_search{lorgunit = make_val(LVal)};
+ _ -> Match
end,
filter_fields(Ds, NewMatch, LServer, mnesia);
-filter_fields([{SVar, [Val]} | Ds], Match, LServer, odbc)
- when is_list(Val) and (Val /= "") ->
+filter_fields([{SVar, [Val]} | Ds], Match, LServer,
+ odbc)
+ when is_binary(Val) and (Val /= <<"">>) ->
LVal = string2lower(Val),
NewMatch = case SVar of
- "user" -> make_val(Match, "lusername", LVal);
- "fn" -> make_val(Match, "lfn", LVal);
- "last" -> make_val(Match, "lfamily", LVal);
- "first" -> make_val(Match, "lgiven", LVal);
- "middle" -> make_val(Match, "lmiddle", LVal);
- "nick" -> make_val(Match, "lnickname", LVal);
- "bday" -> make_val(Match, "lbday", LVal);
- "ctry" -> make_val(Match, "lctry", LVal);
- "locality" -> make_val(Match, "llocality", LVal);
- "email" -> make_val(Match, "lemail", LVal);
- "orgname" -> make_val(Match, "lorgname", LVal);
- "orgunit" -> make_val(Match, "lorgunit", LVal);
- _ -> Match
+ <<"user">> -> make_val(Match, <<"lusername">>, LVal);
+ <<"fn">> -> make_val(Match, <<"lfn">>, LVal);
+ <<"last">> -> make_val(Match, <<"lfamily">>, LVal);
+ <<"first">> -> make_val(Match, <<"lgiven">>, LVal);
+ <<"middle">> -> make_val(Match, <<"lmiddle">>, LVal);
+ <<"nick">> -> make_val(Match, <<"lnickname">>, LVal);
+ <<"bday">> -> make_val(Match, <<"lbday">>, LVal);
+ <<"ctry">> -> make_val(Match, <<"lctry">>, LVal);
+ <<"locality">> ->
+ make_val(Match, <<"llocality">>, LVal);
+ <<"email">> -> make_val(Match, <<"lemail">>, LVal);
+ <<"orgname">> -> make_val(Match, <<"lorgname">>, LVal);
+ <<"orgunit">> -> make_val(Match, <<"lorgunit">>, LVal);
+ _ -> Match
end,
filter_fields(Ds, NewMatch, LServer, odbc);
filter_fields([_ | Ds], Match, LServer, DBType) ->
filter_fields(Ds, Match, LServer, DBType).
make_val(Match, Field, Val) ->
- Condition =
- case lists:suffix("*", Val) of
- true ->
- Val1 = lists:sublist(Val, length(Val) - 1),
- SVal = ejabberd_odbc:escape_like(Val1) ++ "%",
- [Field, " LIKE '", SVal, "'"];
- _ ->
- SVal = ejabberd_odbc:escape(Val),
- [Field, " = '", SVal, "'"]
- end,
+ Condition = case str:suffix(<<"*">>, Val) of
+ true ->
+ Val1 = str:substr(Val, 1, byte_size(Val) - 1),
+ SVal = <<(ejabberd_odbc:escape_like(Val1))/binary,
+ "%">>,
+ [Field, <<" LIKE '">>, SVal, <<"'">>];
+ _ ->
+ SVal = ejabberd_odbc:escape(Val),
+ [Field, <<" = '">>, SVal, <<"'">>]
+ end,
case Match of
- "" ->
- Condition;
- _ ->
- [Match, " and ", Condition]
+ <<"">> -> Condition;
+ _ -> [Match, <<" and ">>, Condition]
end.
make_val(Val) ->
- case lists:suffix("*", Val) of
- true ->
- lists:sublist(Val, length(Val) - 1) ++ '_';
- _ ->
- Val
+ case str:suffix(<<"*">>, Val) of
+ true -> [str:substr(Val, 1, byte_size(Val) - 1)] ++ '_';
+ _ -> Val
end.
find_my_host(LServer) ->
- Parts = string:tokens(LServer, "."),
+ Parts = str:tokens(LServer, <<".">>),
find_my_host(Parts, ?MYHOSTS).
-find_my_host([], _Hosts) ->
- ?MYNAME;
+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)
+ 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, $.).
-
-
+ str:strip(list_to_binary(
+ lists:map(fun (S) -> <<S/binary, $.>> end, Parts)),
+ right, $.).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
set_vcard_t(R, _) ->
US = R#vcard.us,
- User = US,
+ User = US,
VCARD = R#vcard.vcard,
-
- FN = xml:get_path_s(VCARD, [{elem, "FN"}, cdata]),
- Family = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "FAMILY"}, cdata]),
- Given = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "GIVEN"}, cdata]),
- Middle = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "MIDDLE"}, cdata]),
- Nickname = xml:get_path_s(VCARD, [{elem, "NICKNAME"}, cdata]),
- BDay = xml:get_path_s(VCARD, [{elem, "BDAY"}, cdata]),
- CTRY = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "CTRY"}, cdata]),
- Locality = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "LOCALITY"},cdata]),
- EMail = xml:get_path_s(VCARD, [{elem, "EMAIL"}, cdata]),
- OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]),
- OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]),
-
+ FN = xml:get_path_s(VCARD, [{elem, <<"FN">>}, cdata]),
+ Family = xml:get_path_s(VCARD,
+ [{elem, <<"N">>}, {elem, <<"FAMILY">>}, cdata]),
+ Given = xml:get_path_s(VCARD,
+ [{elem, <<"N">>}, {elem, <<"GIVEN">>}, cdata]),
+ Middle = xml:get_path_s(VCARD,
+ [{elem, <<"N">>}, {elem, <<"MIDDLE">>}, cdata]),
+ Nickname = xml:get_path_s(VCARD,
+ [{elem, <<"NICKNAME">>}, cdata]),
+ BDay = xml:get_path_s(VCARD,
+ [{elem, <<"BDAY">>}, cdata]),
+ CTRY = xml:get_path_s(VCARD,
+ [{elem, <<"ADR">>}, {elem, <<"CTRY">>}, cdata]),
+ Locality = xml:get_path_s(VCARD,
+ [{elem, <<"ADR">>}, {elem, <<"LOCALITY">>},
+ cdata]),
+ EMail = xml:get_path_s(VCARD,
+ [{elem, <<"EMAIL">>}, cdata]),
+ OrgName = xml:get_path_s(VCARD,
+ [{elem, <<"ORG">>}, {elem, <<"ORGNAME">>}, cdata]),
+ OrgUnit = xml:get_path_s(VCARD,
+ [{elem, <<"ORG">>}, {elem, <<"ORGUNIT">>}, cdata]),
{LUser, _LServer} = US,
- LFN = string2lower(FN),
- LFamily = string2lower(Family),
- LGiven = string2lower(Given),
- LMiddle = string2lower(Middle),
+ LFN = string2lower(FN),
+ LFamily = string2lower(Family),
+ LGiven = string2lower(Given),
+ LMiddle = string2lower(Middle),
LNickname = string2lower(Nickname),
- LBDay = string2lower(BDay),
- LCTRY = string2lower(CTRY),
+ LBDay = string2lower(BDay),
+ LCTRY = string2lower(CTRY),
LLocality = string2lower(Locality),
- LEMail = string2lower(EMail),
- LOrgName = string2lower(OrgName),
- LOrgUnit = string2lower(OrgUnit),
-
- if
- (LUser == error) or
- (LFN == error) or
- (LFamily == error) or
- (LGiven == error) or
- (LMiddle == error) or
- (LNickname == error) or
- (LBDay == error) or
- (LCTRY == error) or
- (LLocality == error) or
- (LEMail == error) or
- (LOrgName == error) or
- (LOrgUnit == error) ->
- {error, badarg};
- true ->
- mnesia:write(
- #vcard_search{us = US,
- user = User, luser = LUser,
- fn = FN, lfn = LFN,
- family = Family, lfamily = LFamily,
- given = Given, lgiven = LGiven,
- middle = Middle, lmiddle = LMiddle,
- nickname = Nickname, lnickname = LNickname,
- bday = BDay, lbday = LBDay,
- ctry = CTRY, lctry = LCTRY,
- locality = Locality, llocality = LLocality,
- email = EMail, lemail = LEMail,
- orgname = OrgName, lorgname = LOrgName,
- orgunit = OrgUnit, lorgunit = LOrgUnit
- })
- end.
-
+ LEMail = string2lower(EMail),
+ LOrgName = string2lower(OrgName),
+ LOrgUnit = string2lower(OrgUnit),
+ mnesia:write(#vcard_search{us = US, user = User,
+ luser = LUser, fn = FN, lfn = LFN,
+ family = Family, lfamily = LFamily,
+ given = Given, lgiven = LGiven,
+ middle = Middle, lmiddle = LMiddle,
+ nickname = Nickname,
+ lnickname = LNickname, bday = BDay,
+ lbday = LBDay, ctry = CTRY, lctry = LCTRY,
+ locality = Locality,
+ llocality = LLocality, email = EMail,
+ lemail = LEMail, orgname = OrgName,
+ lorgname = LOrgName, orgunit = OrgUnit,
+ lorgunit = LOrgUnit}).
reindex_vcards() ->
- F = fun() ->
- mnesia:foldl(fun set_vcard_t/2, [], vcard)
+ F = fun () -> mnesia:foldl(fun set_vcard_t/2, [], vcard)
end,
mnesia:transaction(F).
-
remove_user(User, Server) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
- remove_user(LUser, LServer, gen_mod:db_type(LServer, ?MODULE)).
+ remove_user(LUser, LServer,
+ gen_mod:db_type(LServer, ?MODULE)).
remove_user(LUser, LServer, mnesia) ->
US = {LUser, LServer},
- F = fun() ->
+ F = fun () ->
mnesia:delete({vcard, US}),
mnesia:delete({vcard_search, US})
end,
mnesia:transaction(F);
remove_user(LUser, LServer, odbc) ->
Username = ejabberd_odbc:escape(LUser),
- ejabberd_odbc:sql_transaction(
- LServer,
- [["delete from vcard where username='", Username, "';"],
- ["delete from vcard_search where lusername='", Username, "';"]]).
+ ejabberd_odbc:sql_transaction(LServer,
+ [[<<"delete from vcard where username='">>,
+ Username, <<"';">>],
+ [<<"delete from vcard_search where lusername='">>,
+ Username, <<"';">>]]).
update_tables() ->
update_vcard_table(),
@@ -875,141 +893,115 @@ update_tables() ->
update_vcard_table() ->
Fields = record_info(fields, vcard),
case mnesia:table_info(vcard, attributes) of
- Fields ->
- ok;
- [user, vcard] ->
- ?INFO_MSG("Converting vcard table from "
- "{user, vcard} format", []),
- Host = ?MYNAME,
- {atomic, ok} = mnesia:create_table(
- mod_vcard_tmp_table,
- [{disc_only_copies, [node()]},
- {type, bag},
- {local_content, true},
- {record_name, vcard},
- {attributes, record_info(fields, vcard)}]),
- mnesia:transform_table(vcard, ignore, Fields),
- F1 = fun() ->
- mnesia:write_lock_table(mod_vcard_tmp_table),
- mnesia:foldl(
- fun(#vcard{us = U} = R, _) ->
- mnesia:dirty_write(
- mod_vcard_tmp_table,
- R#vcard{us = {U, Host}})
- end, ok, vcard)
- end,
- mnesia:transaction(F1),
- mnesia:clear_table(vcard),
- F2 = fun() ->
- mnesia:write_lock_table(vcard),
- mnesia:foldl(
- fun(R, _) ->
- mnesia:dirty_write(R)
- end, ok, mod_vcard_tmp_table)
- end,
- mnesia:transaction(F2),
- mnesia:delete_table(mod_vcard_tmp_table);
- _ ->
- ?INFO_MSG("Recreating vcard table", []),
- mnesia:transform_table(vcard, ignore, Fields)
+ Fields ->
+ ejabberd_config:convert_table_to_binary(
+ vcard, Fields, set,
+ fun(#vcard{us = {U, _}}) -> U end,
+ fun(#vcard{us = {U, S}, vcard = El} = R) ->
+ R#vcard{us = {iolist_to_binary(U),
+ iolist_to_binary(S)},
+ vcard = xml:to_xmlel(El)}
+ end);
+ _ ->
+ ?INFO_MSG("Recreating vcard table", []),
+ mnesia:transform_table(vcard, ignore, Fields)
end.
-
update_vcard_search_table() ->
Fields = record_info(fields, vcard_search),
case mnesia:table_info(vcard_search, attributes) of
- Fields ->
- ok;
- [user, luser,
- fn, lfn,
- family, lfamily,
- given, lgiven,
- middle, lmiddle,
- nickname, lnickname,
- bday, lbday,
- ctry, lctry,
- locality, llocality,
- email, lemail,
- orgname, lorgname,
- orgunit, lorgunit] ->
- ?INFO_MSG("Converting vcard_search table from "
- "{user, luser, fn, lfn, family, lfamily, given, lgiven, middle, lmiddle, nickname, lnickname, bday, lbday, ctry, lctry, locality, llocality, email, lemail, orgname, lorgname, orgunit, lorgunit} format", []),
- Host = ?MYNAME,
- {atomic, ok} = mnesia:create_table(
- mod_vcard_tmp_table,
- [{disc_only_copies, [node()]},
- {type, bag},
- {local_content, true},
- {record_name, vcard_search},
- {attributes, record_info(fields, vcard_search)}]),
- F1 = fun() ->
- mnesia:write_lock_table(mod_vcard_tmp_table),
- mnesia:foldl(
- fun({vcard_search,
- User, LUser,
- FN, LFN,
- Family, LFamily,
- Given, LGiven,
- Middle, LMiddle,
- Nickname, LNickname,
- BDay, LBDay,
- CTRY, LCTRY,
- Locality, LLocality,
- EMail, LEMail,
- OrgName, LOrgName,
- OrgUnit, LOrgUnit
- }, _) ->
- mnesia:dirty_write(
- mod_vcard_tmp_table,
- #vcard_search{
- us = {LUser, Host},
- user = {User, Host},
- luser = LUser,
- fn = FN, lfn = LFN,
- family = Family, lfamily = LFamily,
- given = Given, lgiven = LGiven,
- middle = Middle, lmiddle = LMiddle,
- nickname = Nickname, lnickname = LNickname,
- bday = BDay, lbday = LBDay,
- ctry = CTRY, lctry = LCTRY,
- locality = Locality, llocality = LLocality,
- email = EMail, lemail = LEMail,
- orgname = OrgName, lorgname = LOrgName,
- orgunit = OrgUnit, lorgunit = LOrgUnit
- })
- end, ok, vcard_search)
- end,
- mnesia:transaction(F1),
- lists:foreach(fun(I) ->
- mnesia:del_table_index(
- vcard_search,
- element(I, {vcard_search,
- user, luser,
- fn, lfn,
- family, lfamily,
- given, lgiven,
- middle, lmiddle,
- nickname, lnickname,
- bday, lbday,
- ctry, lctry,
- locality, llocality,
- email, lemail,
- orgname, lorgname,
- orgunit, lorgunit}))
- end, mnesia:table_info(vcard_search, index)),
- mnesia:clear_table(vcard_search),
- mnesia:transform_table(vcard_search, ignore, Fields),
- F2 = fun() ->
- mnesia:write_lock_table(vcard_search),
- mnesia:foldl(
- fun(R, _) ->
- mnesia:dirty_write(R)
- end, ok, mod_vcard_tmp_table)
- end,
- mnesia:transaction(F2),
- mnesia:delete_table(mod_vcard_tmp_table);
- _ ->
- ?INFO_MSG("Recreating vcard_search table", []),
- mnesia:transform_table(vcard_search, ignore, Fields)
+ Fields ->
+ ejabberd_config:convert_table_to_binary(
+ vcard_search, Fields, set,
+ fun(#vcard_search{us = {U, _}}) -> U end,
+ fun(#vcard_search{} = VS) ->
+ [vcard_search | L] = tuple_to_list(VS),
+ NewL = lists:map(
+ fun({U, S}) ->
+ {iolist_to_binary(U),
+ iolist_to_binary(S)};
+ (Str) ->
+ iolist_to_binary(Str)
+ end, L),
+ list_to_tuple([vcard_search | NewL])
+ end);
+ _ ->
+ ?INFO_MSG("Recreating vcard_search table", []),
+ mnesia:transform_table(vcard_search, ignore, Fields)
end.
+export(_Server) ->
+ [{vcard,
+ fun(Host, #vcard{us = {LUser, LServer}, vcard = VCARD})
+ when LServer == Host ->
+ Username = ejabberd_odbc:escape(LUser),
+ SVCARD =
+ ejabberd_odbc:escape(xml:element_to_binary(VCARD)),
+ [[<<"delete from vcard where username='">>, Username, <<"';">>],
+ [<<"insert into vcard(username, vcard) values ('">>,
+ Username, <<"', '">>, SVCARD, <<"');">>]];
+ (_Host, _R) ->
+ []
+ end},
+ {vcard_search,
+ fun(Host, #vcard_search{user = {User, LServer}, luser = LUser,
+ fn = FN, lfn = LFN, family = Family,
+ lfamily = LFamily, given = Given,
+ lgiven = LGiven, middle = Middle,
+ lmiddle = LMiddle, nickname = Nickname,
+ lnickname = LNickname, bday = BDay,
+ lbday = LBDay, ctry = CTRY, lctry = LCTRY,
+ locality = Locality, llocality = LLocality,
+ email = EMail, lemail = LEMail,
+ orgname = OrgName, lorgname = LOrgName,
+ orgunit = OrgUnit, lorgunit = LOrgUnit})
+ when LServer == Host ->
+ Username = ejabberd_odbc:escape(User),
+ LUsername = ejabberd_odbc:escape(LUser),
+ SFN = ejabberd_odbc:escape(FN),
+ SLFN = ejabberd_odbc:escape(LFN),
+ SFamily = ejabberd_odbc:escape(Family),
+ SLFamily = ejabberd_odbc:escape(LFamily),
+ SGiven = ejabberd_odbc:escape(Given),
+ SLGiven = ejabberd_odbc:escape(LGiven),
+ SMiddle = ejabberd_odbc:escape(Middle),
+ SLMiddle = ejabberd_odbc:escape(LMiddle),
+ SNickname = ejabberd_odbc:escape(Nickname),
+ SLNickname = ejabberd_odbc:escape(LNickname),
+ SBDay = ejabberd_odbc:escape(BDay),
+ SLBDay = ejabberd_odbc:escape(LBDay),
+ SCTRY = ejabberd_odbc:escape(CTRY),
+ SLCTRY = ejabberd_odbc:escape(LCTRY),
+ SLocality = ejabberd_odbc:escape(Locality),
+ SLLocality = ejabberd_odbc:escape(LLocality),
+ SEMail = ejabberd_odbc:escape(EMail),
+ SLEMail = ejabberd_odbc:escape(LEMail),
+ SOrgName = ejabberd_odbc:escape(OrgName),
+ SLOrgName = ejabberd_odbc:escape(LOrgName),
+ SOrgUnit = ejabberd_odbc:escape(OrgUnit),
+ SLOrgUnit = ejabberd_odbc:escape(LOrgUnit),
+ [[<<"delete from vcard_search where lusername='">>,
+ LUsername, <<"';">>],
+ [<<"insert into vcard_search( username, "
+ "lusername, fn, lfn, family, lfamily, "
+ " given, lgiven, middle, lmiddle, "
+ "nickname, lnickname, bday, lbday, "
+ "ctry, lctry, locality, llocality, "
+ " email, lemail, orgname, lorgname, "
+ "orgunit, lorgunit)values (">>,
+ <<" '">>, Username, <<"', '">>, LUsername,
+ <<"', '">>, SFN, <<"', '">>, SLFN,
+ <<"', '">>, SFamily, <<"', '">>, SLFamily,
+ <<"', '">>, SGiven, <<"', '">>, SLGiven,
+ <<"', '">>, SMiddle, <<"', '">>, SLMiddle,
+ <<"', '">>, SNickname, <<"', '">>, SLNickname,
+ <<"', '">>, SBDay, <<"', '">>, SLBDay,
+ <<"', '">>, SCTRY, <<"', '">>, SLCTRY,
+ <<"', '">>, SLocality, <<"', '">>, SLLocality,
+ <<"', '">>, SEMail, <<"', '">>, SLEMail,
+ <<"', '">>, SOrgName, <<"', '">>, SLOrgName,
+ <<"', '">>, SOrgUnit, <<"', '">>, SLOrgUnit,
+ <<"');">>]];
+ (_Host, _R) ->
+ []
+ end}].