aboutsummaryrefslogtreecommitdiff
path: root/src/mod_admin_p1.erl
diff options
context:
space:
mode:
authorChristophe Romain <christophe.romain@process-one.net>2012-09-11 15:45:59 +0200
committerChristophe Romain <christophe.romain@process-one.net>2012-09-11 15:45:59 +0200
commit011535f0de1a14d6f5f411035bff9eeafec1c612 (patch)
treee60951904fbdc14dc126450c4d7515f51188d4b7 /src/mod_admin_p1.erl
parentMerge branch '2.1.x' into 2.2.x (diff)
binary refactoring
Diffstat (limited to 'src/mod_admin_p1.erl')
-rw-r--r--src/mod_admin_p1.erl1857
1 files changed, 905 insertions, 952 deletions
diff --git a/src/mod_admin_p1.erl b/src/mod_admin_p1.erl
index 0077e5fd1..5716164c3 100644
--- a/src/mod_admin_p1.erl
+++ b/src/mod_admin_p1.erl
@@ -73,55 +73,37 @@
%%%
-module(mod_admin_p1).
+
-author('ProcessOne').
--export([start/2, stop/1,
- %% Erlang
- restart_module/2,
- %% Accounts
- create_account/3,
- delete_account/2,
- change_password/3,
- rename_account/4,
- check_users_registration/1,
- %% Sessions
- get_presence/2,
- get_resources/2,
- %% Vcard
- set_nickname/3,
- %% Roster
- add_rosteritem/6,
- delete_rosteritem/3,
- add_rosteritem_groups/5,
- del_rosteritem_groups/5,
- modify_rosteritem_groups/6,
- link_contacts/6,
- unlink_contacts/2,
- link_contacts/7, unlink_contacts/3, % Versions with Push parameter
- get_roster/2,
- get_roster_with_presence/2,
- add_contacts/3,
- remove_contacts/3,
- %% PubSub
- update_status/4,
- delete_status/3,
- %% Transports
- transport_register/5,
- %% Stanza
- send_chat/3,
- send_message/4,
- send_stanza/3
- ]).
+-export([start/2, stop/1, restart_module/2,
+ create_account/3, delete_account/2, change_password/3,
+ rename_account/4, check_users_registration/1,
+ get_presence/2, get_resources/2, set_nickname/3,
+ add_rosteritem/6, delete_rosteritem/3,
+ add_rosteritem_groups/5, del_rosteritem_groups/5,
+ modify_rosteritem_groups/6, link_contacts/6,
+ unlink_contacts/2, link_contacts/7, unlink_contacts/3,
+ get_roster/2, get_roster_with_presence/2,
+ add_contacts/3, remove_contacts/3, transport_register/5,
+ send_chat/3, send_message/4, send_stanza/3]).
-include("ejabberd.hrl").
+
-include("ejabberd_commands.hrl").
+
-include("mod_roster.hrl").
+
-include("jlib.hrl").
-ifdef(EJABBERD1).
--record(session, {sid, usr, us, priority}). %% ejabberd 1.1.x
+
+-record(session, {sid, usr, us, priority}).
+
-else.
--record(session, {sid, usr, us, priority, info}). %% ejabberd 2.x.x
+
+-record(session, {sid, usr, us, priority, info}).
+
-endif.
start(_Host, _Opts) ->
@@ -135,357 +117,334 @@ stop(_Host) ->
%%%
commands() ->
- [
- #ejabberd_commands{name = restart_module, tags = [erlang],
+ [#ejabberd_commands{name = restart_module,
+ tags = [erlang],
desc = "Stop an ejabberd module, reload code and start",
module = ?MODULE, function = restart_module,
args = [{module, string}, {host, string}],
result = {res, rescode}},
-
- %% Similar to ejabberd_admin register
- #ejabberd_commands{name = create_account, tags = [accounts],
+ #ejabberd_commands{name = create_account,
+ tags = [accounts],
desc = "Create an ejabberd user account",
longdesc = "This command is similar to 'register'.",
module = ?MODULE, function = create_account,
- args = [{user, string}, {server, string},
- {password, string}],
+ args =
+ [{user, string}, {server, string},
+ {password, string}],
result = {res, integer}},
-
- %% Similar to ejabberd_admin unregister
- #ejabberd_commands{name = delete_account, tags = [accounts],
+ #ejabberd_commands{name = delete_account,
+ tags = [accounts],
desc = "Remove an account from the server",
longdesc = "This command is similar to 'unregister'.",
module = ?MODULE, function = delete_account,
args = [{user, string}, {server, string}],
result = {res, integer}},
-
- #ejabberd_commands{name = rename_account, tags = [accounts],
- desc = "Change an acount name",
- longdesc = "Creates a new account "
- "and copies the roster from the old one, and updates the rosters of his contacts. "
- "Offline messages and private storage are lost.",
+ #ejabberd_commands{name = rename_account,
+ tags = [accounts], desc = "Change an acount name",
+ longdesc =
+ "Creates a new account and copies the "
+ "roster from the old one, and updates "
+ "the rosters of his contacts. Offline "
+ "messages and private storage are lost.",
module = ?MODULE, function = rename_account,
- args = [{user, string}, {server, string},
- {newuser, string}, {newserver, string}],
+ args =
+ [{user, string}, {server, string},
+ {newuser, string}, {newserver, string}],
result = {res, integer}},
-
- %% This command is also implemented in mod_admin_contrib
- #ejabberd_commands{name = change_password, tags = [accounts],
- desc = "Change the password on behalf of the given user",
+ #ejabberd_commands{name = change_password,
+ tags = [accounts],
+ desc =
+ "Change the password on behalf of the given user",
module = ?MODULE, function = change_password,
- args = [{user, string}, {server, string},
- {newpass, string}],
+ args =
+ [{user, string}, {server, string},
+ {newpass, string}],
result = {res, integer}},
-
- %% This command is also implemented in mod_admin_contrib
#ejabberd_commands{name = set_nickname, tags = [vcard],
desc = "Define user nickname",
- longdesc = "Set/updated nickname in the user Vcard. "
- "Other informations are unchanged.",
+ longdesc =
+ "Set/updated nickname in the user Vcard. "
+ "Other informations are unchanged.",
module = ?MODULE, function = set_nickname,
- args = [{user, string}, {server, string}, {nick,string}],
+ args =
+ [{user, string}, {server, string}, {nick, string}],
result = {res, integer}},
-
- %% This command is also implemented in mod_admin_contrib
- #ejabberd_commands{name = add_rosteritem, tags = [roster],
+ #ejabberd_commands{name = add_rosteritem,
+ tags = [roster],
desc = "Add an entry in a user's roster",
- longdesc = "Some arguments are:\n"
- " - jid: the JabberID of the user you would "
- "like to add in user roster on the server.\n"
- " - subs: the state of the roster item subscription.\n\n"
- "The allowed values of the 'subs' argument are: both, to, from or none.\n"
- " - none: presence packets are not sent between parties.\n"
- " - both: presence packets are sent in both direction.\n"
- " - to: the user sees the presence of the given JID.\n"
- " - from: the JID specified sees the user presence.\n\n"
- "ejabberd sends to the user's connected client both the roster item and the presence."
- "Don't forget that roster items should keep symmetric: "
- "when adding a roster item for a user, "
- "you have to do the symmetric roster item addition.\n\n",
+ longdesc =
+ "Some arguments are:\n - jid: the JabberID "
+ "of the user you would like to add in "
+ "user roster on the server.\n - subs: "
+ "the state of the roster item subscription.\n\n"
+ "The allowed values of the 'subs' argument "
+ "are: both, to, from or none.\n - none: "
+ "presence packets are not sent between "
+ "parties.\n - both: presence packets "
+ "are sent in both direction.\n - to: "
+ "the user sees the presence of the given "
+ "JID.\n - from: the JID specified sees "
+ "the user presence.\n\nejabberd sends "
+ "to the user's connected client both "
+ "the roster item and the presence.Don't "
+ "forget that roster items should keep "
+ "symmetric: when adding a roster item "
+ "for a user, you have to do the symmetric "
+ "roster item addition.\n\n",
module = ?MODULE, function = add_rosteritem,
- args = [{user, string}, {server, string}, {jid, string},
- {group, string}, {nick, string}, {subs, string}],
+ args =
+ [{user, string}, {server, string}, {jid, string},
+ {group, string}, {nick, string}, {subs, string}],
result = {res, integer}},
-
- %% This command is also implemented in mod_admin_contrib
- #ejabberd_commands{name = delete_rosteritem, tags = [roster],
+ #ejabberd_commands{name = delete_rosteritem,
+ tags = [roster],
desc = "Remove a roster item from the user's roster",
- longdesc = "Roster items should be kept symmetric: "
- "when removing a roster item for a user you have to do "
- "the symmetric roster item removal. \n\n"
- "ejabberd sends to the user's connected client both the roster item removel and the presence unsubscription."
- "This mechanism bypass the standard roster approval "
- "addition mechanism and should only be used for server "
- "administration or server integration purpose.",
+ longdesc =
+ "Roster items should be kept symmetric: "
+ "when removing a roster item for a user "
+ "you have to do the symmetric roster "
+ "item removal. \n\nejabberd sends to "
+ "the user's connected client both the "
+ "roster item removel and the presence "
+ "unsubscription.This mechanism bypass "
+ "the standard roster approval addition "
+ "mechanism and should only be used for "
+ "server administration or server integration "
+ "purpose.",
module = ?MODULE, function = delete_rosteritem,
- args = [{user, string}, {server, string}, {jid, string}],
+ args =
+ [{user, string}, {server, string}, {jid, string}],
result = {res, integer}},
-
- #ejabberd_commands{name = add_rosteritem_groups, tags = [roster],
+ #ejabberd_commands{name = add_rosteritem_groups,
+ tags = [roster],
desc = "Add new groups in an existing roster item",
- longdesc = "The argument Groups must be a string with group names separated by the character ;",
+ longdesc =
+ "The argument Groups must be a string "
+ "with group names separated by the character ;",
module = ?MODULE, function = add_rosteritem_groups,
- args = [{user, string}, {server, string}, {jid, string},
- {groups, string}, {push, string}],
+ args =
+ [{user, string}, {server, string}, {jid, string},
+ {groups, string}, {push, string}],
result = {res, integer}},
-
- #ejabberd_commands{name = del_rosteritem_groups, tags = [roster],
+ #ejabberd_commands{name = del_rosteritem_groups,
+ tags = [roster],
desc = "Delete groups in an existing roster item",
- longdesc = "The argument Groups must be a string with group names separated by the character ;",
+ longdesc =
+ "The argument Groups must be a string "
+ "with group names separated by the character ;",
module = ?MODULE, function = del_rosteritem_groups,
- args = [{user, string}, {server, string}, {jid, string},
- {groups, string}, {push, string}],
+ args =
+ [{user, string}, {server, string}, {jid, string},
+ {groups, string}, {push, string}],
result = {res, integer}},
-
- #ejabberd_commands{name = modify_rosteritem_groups, tags = [roster],
+ #ejabberd_commands{name = modify_rosteritem_groups,
+ tags = [roster],
desc = "Modify the groups of an existing roster item",
- longdesc = "The argument Groups must be a string with group names separated by the character ;",
+ longdesc =
+ "The argument Groups must be a string "
+ "with group names separated by the character ;",
module = ?MODULE, function = modify_rosteritem_groups,
- args = [{user, string}, {server, string}, {jid, string},
- {groups, string}, {subs, string}, {push, string}],
+ args =
+ [{user, string}, {server, string}, {jid, string},
+ {groups, string}, {subs, string}, {push, string}],
result = {res, integer}},
-
- #ejabberd_commands{name = link_contacts, tags = [roster],
+ #ejabberd_commands{name = link_contacts,
+ tags = [roster],
desc = "Add a symmetrical entry in two users roster",
- longdesc = "jid1 is the JabberID of the user1 you would "
- "like to add in user2 roster on the server.\n"
- "nick1 is the nick of user1.\n"
- "group1 is the group name when adding user1 to user2 roster.\n"
- "jid2 is the JabberID of the user2 you would like to "
- "add in user1 roster on the server.\n"
- "nick2 is the nick of user2.\n"
- "group2 is the group name when adding user2 to user1 roster.\n\n"
- "This mechanism bypasses the standard roster approval "
- "addition mechanism "
- "and should only be userd for server administration or "
- "server integration purpose.",
+ longdesc =
+ "jid1 is the JabberID of the user1 you "
+ "would like to add in user2 roster on "
+ "the server.\nnick1 is the nick of user1.\ngro"
+ "up1 is the group name when adding user1 "
+ "to user2 roster.\njid2 is the JabberID "
+ "of the user2 you would like to add in "
+ "user1 roster on the server.\nnick2 is "
+ "the nick of user2.\ngroup2 is the group "
+ "name when adding user2 to user1 roster.\n\nTh"
+ "is mechanism bypasses the standard roster "
+ "approval addition mechanism and should "
+ "only be userd for server administration "
+ "or server integration purpose.",
module = ?MODULE, function = link_contacts,
- args = [{jid1, string}, {nick1, string}, {group1, string}, {jid2, string}, {nick2, string}, {group2, string}],
+ args =
+ [{jid1, string}, {nick1, string}, {group1, string},
+ {jid2, string}, {nick2, string}, {group2, string}],
result = {res, integer}},
-
- #ejabberd_commands{name = unlink_contacts, tags = [roster],
+ #ejabberd_commands{name = unlink_contacts,
+ tags = [roster],
desc = "Remove a symmetrical entry in two users roster",
- longdesc = "jid1 is the JabberID of the user1.\n"
- "jid2 is the JabberID of the user2.\n\n"
- "This mechanism bypass the standard roster approval "
- "addition mechanism "
- "and should only be used for server administration or "
- "server integration purpose.",
+ longdesc =
+ "jid1 is the JabberID of the user1.\njid2 "
+ "is the JabberID of the user2.\n\nThis "
+ "mechanism bypass the standard roster "
+ "approval addition mechanism and should "
+ "only be used for server administration "
+ "or server integration purpose.",
module = ?MODULE, function = unlink_contacts,
args = [{jid1, string}, {jid2, string}],
result = {res, integer}},
-
- %% TODO: test
- %% This command is not supported by ejabberdctl
#ejabberd_commands{name = add_contacts, tags = [roster],
- desc = "Call add_rosteritem with subscription \"both\" "
- "for a given list of contacts",
+ desc =
+ "Call add_rosteritem with subscription "
+ "\"both\" for a given list of contacts",
module = ?MODULE, function = add_contacts,
- args = [{user, string},
- {server, string},
- {contacts, {list,
- {contact, {tuple, [
- {jid, string},
- {group, string},
- {nick, string}
- ]}}
- }}
- ],
+ args =
+ [{user, string}, {server, string},
+ {contacts,
+ {list,
+ {contact,
+ {tuple,
+ [{jid, string}, {group, string},
+ {nick, string}]}}}}],
result = {res, integer}},
- %% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, add_contacts, [{struct,
- %% [{user, "badlop"},
- %% {server, "localhost"},
- %% {contacts, {array, [{struct, [
- %% {contact, {array, [{struct, [
- %% {group, "Friends"},
- %% {jid, "tom@localhost"},
- %% {nick, "Tom"}
- %% ]}]}}
- %% ]}]}}
- %% ]
- %% }]}).
-
- %% TODO: test
- %% This command is not supported by ejabberdctl
- #ejabberd_commands{name = remove_contacts, tags = [roster],
+ #ejabberd_commands{name = remove_contacts,
+ tags = [roster],
desc = "Call del_rosteritem for a list of contacts",
module = ?MODULE, function = remove_contacts,
- args = [{user, string},
- {server, string},
- {contacts, {list,
- {jid, string}
- }}
- ],
+ args =
+ [{user, string}, {server, string},
+ {contacts, {list, {jid, string}}}],
result = {res, integer}},
- %% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, remove_contacts, [{struct,
- %% [{user, "badlop"},
- %% {server, "localhost"},
- %% {contacts, {array, [{struct, [
- %% {jid, "tom@localhost"}
- %% ]}]}}
- %% ]
- %% }]}).
-
- %% TODO: test
- %% This command is not supported by ejabberdctl
- #ejabberd_commands{name = check_users_registration, tags = [roster],
+ #ejabberd_commands{name = check_users_registration,
+ tags = [roster],
desc = "List registration status for a list of users",
module = ?MODULE, function = check_users_registration,
- args = [{users, {list,
- {auser, {tuple, [
- {user, string},
- {server, string}
- ]}}
- }}
- ],
- result = {users, {list,
- {auser, {tuple, [
- {user, string},
- {server, string},
- {status, integer}
- ]}}
- }}},
- %% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, check_users_registration, [{struct,
- %% [{users, {array, [{struct, [
- %% {auser, {array, [{struct, [
- %% {user, "badlop"},
- %% {server, "localhost"}
- %% ]}]}}
- %% ]}]}}]
- %% }]}).
-
- %% This command is also implemented in mod_admin_contrib
+ args =
+ [{users,
+ {list,
+ {auser,
+ {tuple, [{user, string}, {server, string}]}}}}],
+ result =
+ {users,
+ {list,
+ {auser,
+ {tuple,
+ [{user, string}, {server, string},
+ {status, integer}]}}}}},
#ejabberd_commands{name = get_roster, tags = [roster],
desc = "Retrieve the roster for a given user",
- longdesc = "Returns a list of the contacts in a user "
- "roster.\n\n"
- "Also returns the state of the contact subscription. "
- "Subscription can be either "
- " \"none\", \"from\", \"to\", \"both\". "
- "Pending can be \"in\", \"out\" or \"none\".",
+ longdesc =
+ "Returns a list of the contacts in a "
+ "user roster.\n\nAlso returns the state "
+ "of the contact subscription. Subscription "
+ "can be either \"none\", \"from\", \"to\", "
+ "\"both\". Pending can be \"in\", \"out\" "
+ "or \"none\".",
module = ?MODULE, function = get_roster,
args = [{user, string}, {server, string}],
- result = {contacts, {list, {contact, {tuple, [{jid, string}, {groups, {list, {group, string}}},
- {nick, string}, {subscription, string}, {pending, string}]}}}}},
-
- #ejabberd_commands{name = get_roster_with_presence, tags = [roster],
- desc = "Retrieve the roster for a given user including "
- "presence information",
- longdesc = "The 'show' value contains the user presence. "
- "It can take limited values:\n"
- " - available\n"
- " - chat (Free for chat)\n"
- " - away\n"
- " - dnd (Do not disturb)\n"
- " - xa (Not available, extended away)\n"
- " - unavailable (Not connected)\n\n"
- "'status' is a free text defined by the user client.\n\n"
- "Also returns the state of the contact subscription. "
- "Subscription can be either "
- "\"none\", \"from\", \"to\", \"both\". "
- "Pending can be \"in\", \"out\" or \"none\".\n\n"
- "Note: If user is connected several times, only keep the"
- " resource with the highest non-negative priority.",
+ result =
+ {contacts,
+ {list,
+ {contact,
+ {tuple,
+ [{jid, string},
+ {groups, {list, {group, string}}},
+ {nick, string}, {subscription, string},
+ {pending, string}]}}}}},
+ #ejabberd_commands{name = get_roster_with_presence,
+ tags = [roster],
+ desc =
+ "Retrieve the roster for a given user "
+ "including presence information",
+ longdesc =
+ "The 'show' value contains the user presence. "
+ "It can take limited values:\n - available\n "
+ "- chat (Free for chat)\n - away\n - "
+ "dnd (Do not disturb)\n - xa (Not available, "
+ "extended away)\n - unavailable (Not "
+ "connected)\n\n'status' is a free text "
+ "defined by the user client.\n\nAlso "
+ "returns the state of the contact subscription"
+ ". Subscription can be either \"none\", "
+ "\"from\", \"to\", \"both\". Pending "
+ "can be \"in\", \"out\" or \"none\".\n\nNote: "
+ "If user is connected several times, "
+ "only keep the resource with the highest "
+ "non-negative priority.",
module = ?MODULE, function = get_roster_with_presence,
args = [{user, string}, {server, string}],
- result = {contacts, {list, {contact, {tuple, [{jid, string}, {resource, string}, {group, string}, {nick, string}, {subscription, string}, {pending, string}, {show, string}, {status, string}]}}}}},
-
- #ejabberd_commands{name = get_presence, tags = [session],
- desc = "Retrieve the resource with highest priority, "
- "and its presence (show and status message) for a given "
- "user.",
- longdesc = "The 'jid' value contains the user jid with "
- "resource.\n"
- "The 'show' value contains the user presence flag. "
- "It can take limited values:\n"
- " - available\n"
- " - chat (Free for chat)\n"
- " - away\n"
- " - dnd (Do not disturb)\n"
- " - xa (Not available, extended away)\n"
- " - unavailable (Not connected)\n\n"
- "'status' is a free text defined by the user client.",
+ result =
+ {contacts,
+ {list,
+ {contact,
+ {tuple,
+ [{jid, string}, {resource, string},
+ {group, string}, {nick, string},
+ {subscription, string}, {pending, string},
+ {show, string}, {status, string}]}}}}},
+ #ejabberd_commands{name = get_presence,
+ tags = [session],
+ desc =
+ "Retrieve the resource with highest priority, "
+ "and its presence (show and status message) "
+ "for a given user.",
+ longdesc =
+ "The 'jid' value contains the user jid "
+ "with resource.\nThe 'show' value contains "
+ "the user presence flag. It can take "
+ "limited values:\n - available\n - chat "
+ "(Free for chat)\n - away\n - dnd (Do "
+ "not disturb)\n - xa (Not available, "
+ "extended away)\n - unavailable (Not "
+ "connected)\n\n'status' is a free text "
+ "defined by the user client.",
module = ?MODULE, function = get_presence,
args = [{user, string}, {server, string}],
- result = {presence, {tuple, [{jid, string},
- {show, string},
- {status, string}]}}},
-
- #ejabberd_commands{name = get_resources, tags = [session],
+ result =
+ {presence,
+ {tuple,
+ [{jid, string}, {show, string},
+ {status, string}]}}},
+ #ejabberd_commands{name = get_resources,
+ tags = [session],
desc = "Get all available resources for a given user",
module = ?MODULE, function = get_resources,
args = [{user, string}, {server, string}],
result = {resources, {list, {resource, string}}}},
-
- %% PubSub
- #ejabberd_commands{name = update_status, tags = [pubsub],
- desc = "Update the status on behalf of a user",
- longdesc =
- "jid: the JabberID of the user. Example: user@domain.\n\n"
- "node: the reference of the node to publish on.\n"
- "Example: http://process-one.net/protocol/availability\n\n"
- "itemid: the reference of the item (in our case profile ID).\n\n"
- "payload: the payload of the publish operation in XML.\n"
- "The string has to be properly escaped to comply with XML formalism of XML RPC.",
- module = ?MODULE, function = update_status,
- args = [{jid, string}, {node, string}, {itemid, string}, {payload, string}],
- result = {res, string}},
-
- #ejabberd_commands{name = delete_status, tags = [pubsub],
- desc = "Delete the status on behalf of a user",
- longdesc =
- "jid: the JabberID of the user. Example: user@domain.\n\n"
- "node: the reference of the node to publish on.\n"
- "Example: http://process-one.net/protocol/availability\n\n"
- "itemid: the reference of the item (in our case profile ID).",
- module = ?MODULE, function = delete_status,
- args = [{jid, string}, {node, string}, {itemid, string}],
- result = {res, string}},
-
- #ejabberd_commands{name = transport_register, tags = [transports],
+ #ejabberd_commands{name = transport_register,
+ tags = [transports],
desc = "Register a user in a transport",
module = ?MODULE, function = transport_register,
- args = [{host, string}, {transport, string},
- {jidstring, string}, {username, string}, {password, string}],
+ args =
+ [{host, string}, {transport, string},
+ {jidstring, string}, {username, string},
+ {password, string}],
result = {res, string}},
-
- %% Similar to mod_admin_contrib send_message which sends a headline
#ejabberd_commands{name = send_chat, tags = [stanza],
desc = "Send chat message to a given user",
module = ?MODULE, function = send_chat,
args = [{from, string}, {to, string}, {body, string}],
result = {res, integer}},
-
#ejabberd_commands{name = send_message, tags = [stanza],
desc = "Send normal message to a given user",
module = ?MODULE, function = send_message,
- args = [{from, string}, {to, string},
- {subject, string}, {body, string}],
+ args =
+ [{from, string}, {to, string}, {subject, string},
+ {body, string}],
result = {res, integer}},
-
#ejabberd_commands{name = send_stanza, tags = [stanza],
desc = "Send stanza to a given user",
- longdesc = "If Stanza contains a \"from\" field, "
- "then it overrides the passed from argument."
- "If Stanza contains a \"to\" field, then it overrides "
- "the passed to argument.",
+ longdesc =
+ "If Stanza contains a \"from\" field, "
+ "then it overrides the passed from argument.If "
+ "Stanza contains a \"to\" field, then "
+ "it overrides the passed to argument.",
module = ?MODULE, function = send_stanza,
- args = [{user, string}, {server, string},
- {stanza, string}],
- result = {res, integer}}
- ].
-
+ args =
+ [{user, string}, {server, string},
+ {stanza, string}],
+ result = {res, integer}}].
%%%
%%% Erlang
%%%
restart_module(ModuleString, Host) ->
- Module = list_to_atom(ModuleString),
+ Module = jlib:binary_to_atom(ModuleString),
List = gen_mod:loaded_modules_with_opts(Host),
- Opts = case lists:keysearch(Module,1, List) of
- {value, {_, O}} -> O;
- _ -> []
+ Opts = case lists:keysearch(Module, 1, List) of
+ {value, {_, O}} -> O;
+ _ -> []
end,
gen_mod:stop_module(Host, Module),
code:delete(Module),
@@ -493,115 +452,130 @@ restart_module(ModuleString, Host) ->
gen_mod:start_module(Host, Module, Opts),
ok.
-
%%%
%%% Accounts
%%%
create_account(U, S, P) ->
case ejabberd_auth:try_register(U, S, P) of
- {atomic, ok} ->
- 0;
- {atomic, exists} ->
- 409;
- _ ->
- 1
+ {atomic, ok} -> 0;
+ {atomic, exists} -> 409;
+ _ -> 1
end.
delete_account(U, S) ->
- Fun = fun() -> ejabberd_auth:remove_user(U, S) end,
+ Fun = fun () -> ejabberd_auth:remove_user(U, S) end,
user_action(U, S, Fun, ok).
change_password(U, S, P) ->
- Fun = fun() -> ejabberd_auth:set_password(U, S, P) end,
+ Fun = fun () -> ejabberd_auth:set_password(U, S, P) end,
user_action(U, S, Fun, ok).
rename_account(U, S, NU, NS) ->
case ejabberd_auth:is_user_exists(U, S) of
- true ->
- case ejabberd_auth:get_password(U, S) of
- false ->
- 1;
- Password ->
- case ejabberd_auth:try_register(NU, NS, Password) of
- {atomic, ok} ->
- OldJID = jlib:jid_to_string({U, S, ""}),
- NewJID = jlib:jid_to_string({NU, NS, ""}),
- Roster = get_roster2(U, S),
- lists:foreach(fun(#roster{jid={RU, RS, RE}, name=Nick, groups=Groups}) ->
- NewGroup = extract_group(Groups),
- {NewNick, Group} = case lists:filter(fun(#roster{jid={PU, PS, _}}) ->
- (PU == U) and (PS == S)
- end, get_roster2(RU, RS)) of
- [#roster{name=OldNick, groups=OldGroups}|_] -> {OldNick, extract_group(OldGroups)};
- [] -> {NU, []}
- end,
- JIDStr = jlib:jid_to_string({RU, RS, RE}),
- link_contacts2(NewJID, NewNick, NewGroup, JIDStr, Nick, Group, true),
- unlink_contacts2(OldJID, JIDStr, true)
- end, Roster),
- ejabberd_auth:remove_user(U, S),
- 0;
- {atomic, exists} ->
- 409;
- _ ->
- 1
- end
- end;
- false ->
- 404
+ true ->
+ case ejabberd_auth:get_password(U, S) of
+ false -> 1;
+ Password ->
+ case ejabberd_auth:try_register(NU, NS, Password) of
+ {atomic, ok} ->
+ OldJID = jlib:jid_to_string({U, S, <<"">>}),
+ NewJID = jlib:jid_to_string({NU, NS, <<"">>}),
+ Roster = get_roster2(U, S),
+ lists:foreach(fun (#roster{jid = {RU, RS, RE},
+ name = Nick,
+ groups = Groups}) ->
+ NewGroup = extract_group(Groups),
+ {NewNick, Group} = case
+ lists:filter(fun
+ (#roster{jid
+ =
+ {PU,
+ PS,
+ _}}) ->
+ (PU
+ ==
+ U)
+ and
+ (PS
+ ==
+ S)
+ end,
+ get_roster2(RU,
+ RS))
+ of
+ [#roster{name =
+ OldNick,
+ groups
+ =
+ OldGroups}
+ | _] ->
+ {OldNick,
+ extract_group(OldGroups)};
+ [] -> {NU, []}
+ end,
+ JIDStr = jlib:jid_to_string({RU, RS,
+ RE}),
+ link_contacts2(NewJID, NewNick,
+ NewGroup, JIDStr,
+ Nick, Group, true),
+ unlink_contacts2(OldJID, JIDStr,
+ true)
+ end,
+ Roster),
+ ejabberd_auth:remove_user(U, S),
+ 0;
+ {atomic, exists} -> 409;
+ _ -> 1
+ end
+ end;
+ false -> 404
end.
-
%%%
%%% Sessions
%%%
get_presence(U, S) ->
case ejabberd_auth:is_user_exists(U, S) of
- true ->
- {Resource, Show, Status} = get_presence2(U, S),
- FullJID = case Resource of
- [] ->
- lists:flatten([U,"@",S]);
- _ ->
- lists:flatten([U,"@",S,"/",Resource])
- end,
- {FullJID, Show, Status};
- false ->
- 404
+ true ->
+ {Resource, Show, Status} = get_presence2(U, S),
+ FullJID = jlib:jid_to_string({U, S, Resource}),
+ {FullJID, Show, Status};
+ false -> 404
end.
get_resources(U, S) ->
case ejabberd_auth:is_user_exists(U, S) of
- true ->
- get_resources2(U, S);
- false ->
- 404
+ true -> get_resources2(U, S);
+ false -> 404
end.
-
%%%
%%% Vcard
%%%
set_nickname(U, S, N) ->
- Fun = fun() -> case mod_vcard:process_sm_iq(
- {jid, U, S, "", U, S, ""},
- {jid, U, S, "", U, S, ""},
- {iq, "", set, "", "en",
- {xmlelement, "vCard",
- [{"xmlns", "vcard-temp"}], [
- {xmlelement, "NICKNAME", [], [{xmlcdata, N}]}
- ]
- }}) of
- {iq, [], result, [], _, []} -> ok;
- _ -> error
- end
+ JID = jlib:make_jid({U, S, <<"">>}),
+ Fun = fun () ->
+ case mod_vcard:process_sm_iq(
+ JID, JID,
+ #iq{type = set,
+ lang = <<"en">>,
+ sub_el =
+ #xmlel{name = <<"vCard">>,
+ attrs = [{<<"xmlns">>, ?NS_VCARD}],
+ children =
+ [#xmlel{name = <<"NICKNAME">>,
+ attrs = [],
+ children =
+ [{xmlcdata, N}]}]}}) of
+ #iq{type = result} -> ok;
+ _ -> error
+ end
end,
user_action(U, S, Fun, ok).
-
%%%
%%% Roster
%%%
@@ -610,343 +584,349 @@ add_rosteritem(U, S, JID, G, N, Subs) ->
add_rosteritem(U, S, JID, G, N, Subs, true).
add_rosteritem(U, S, JID, G, N, Subs, Push) ->
- Fun = fun() -> add_rosteritem2(U, S, JID, N, G, Subs, Push) end,
+ Fun = fun () ->
+ add_rosteritem2(U, S, JID, N, G, Subs, Push)
+ end,
user_action(U, S, Fun, {atomic, ok}).
-link_contacts(JID1, Nick1, Group1, JID2, Nick2, Group2) ->
- link_contacts(JID1, Nick1, Group1, JID2, Nick2, Group2, true).
-
-link_contacts(JID1, Nick1, Group1, JID2, Nick2, Group2, Push) ->
- {U1, S1, _} = jlib:jid_tolower(jlib:string_to_jid(JID1)),
- {U2, S2, _} = jlib:jid_tolower(jlib:string_to_jid(JID2)),
- case {ejabberd_auth:is_user_exists(U1, S1), ejabberd_auth:is_user_exists(U2, S2)} of
- {true, true} ->
- case link_contacts2(JID1, Nick1, Group1, JID2, Nick2, Group2, Push) of
- {atomic, ok} ->
- 0;
- _ ->
- 1
- end;
- _ ->
- 404
+link_contacts(JID1, Nick1, Group1, JID2, Nick2,
+ Group2) ->
+ link_contacts(JID1, Nick1, Group1, JID2, Nick2, Group2,
+ true).
+
+link_contacts(JID1, Nick1, Group1, JID2, Nick2, Group2,
+ Push) ->
+ {U1, S1, _} =
+ jlib:jid_tolower(jlib:string_to_jid(JID1)),
+ {U2, S2, _} =
+ jlib:jid_tolower(jlib:string_to_jid(JID2)),
+ case {ejabberd_auth:is_user_exists(U1, S1),
+ ejabberd_auth:is_user_exists(U2, S2)}
+ of
+ {true, true} ->
+ case link_contacts2(JID1, Nick1, Group1, JID2, Nick2,
+ Group2, Push)
+ of
+ {atomic, ok} -> 0;
+ _ -> 1
+ end;
+ _ -> 404
end.
delete_rosteritem(U, S, JID) ->
- Fun = fun() -> del_rosteritem(U, S, JID) end,
+ Fun = fun () -> del_rosteritem(U, S, JID) end,
user_action(U, S, Fun, {atomic, ok}).
unlink_contacts(JID1, JID2) ->
unlink_contacts(JID1, JID2, true).
unlink_contacts(JID1, JID2, Push) ->
- {U1, S1, _} = jlib:jid_tolower(jlib:string_to_jid(JID1)),
- {U2, S2, _} = jlib:jid_tolower(jlib:string_to_jid(JID2)),
- case {ejabberd_auth:is_user_exists(U1, S1), ejabberd_auth:is_user_exists(U2, S2)} of
- {true, true} ->
- case unlink_contacts2(JID1, JID2, Push) of
- {atomic, ok} ->
- 0;
- _ ->
- 1
- end;
- _ ->
- 404
+ {U1, S1, _} =
+ jlib:jid_tolower(jlib:string_to_jid(JID1)),
+ {U2, S2, _} =
+ jlib:jid_tolower(jlib:string_to_jid(JID2)),
+ case {ejabberd_auth:is_user_exists(U1, S1),
+ ejabberd_auth:is_user_exists(U2, S2)}
+ of
+ {true, true} ->
+ case unlink_contacts2(JID1, JID2, Push) of
+ {atomic, ok} -> 0;
+ _ -> 1
+ end;
+ _ -> 404
end.
get_roster(U, S) ->
case ejabberd_auth:is_user_exists(U, S) of
- true ->
- format_roster(get_roster2(U, S));
- false ->
- 404
+ true -> format_roster(get_roster2(U, S));
+ false -> 404
end.
get_roster_with_presence(U, S) ->
case ejabberd_auth:is_user_exists(U, S) of
- true ->
- format_roster_with_presence(get_roster2(U, S));
- false ->
- 404
+ true -> format_roster_with_presence(get_roster2(U, S));
+ false -> 404
end.
add_contacts(U, S, Contacts) ->
case ejabberd_auth:is_user_exists(U, S) of
- true ->
- JID1 = jlib:jid_to_string({U, S, ""}),
- lists:foldl(fun({JID2, Group, Nick}, Acc) ->
- {PU, PS, _} = jlib:jid_tolower(jlib:string_to_jid(JID2)),
- case ejabberd_auth:is_user_exists(PU, PS) of
- true ->
- case link_contacts2(JID1, "", Group, JID2, Nick, Group, true) of
- {atomic, ok} -> Acc;
- _ -> 1
- end;
- false ->
- Acc
- end
- end, 0, Contacts);
- false ->
- 404
+ true ->
+ JID1 = jlib:jid_to_string({U, S, <<"">>}),
+ lists:foldl(fun ({JID2, Group, Nick}, Acc) ->
+ {PU, PS, _} =
+ jlib:jid_tolower(jlib:string_to_jid(JID2)),
+ case ejabberd_auth:is_user_exists(PU, PS) of
+ true ->
+ case link_contacts2(JID1, <<"">>, Group,
+ JID2, Nick, Group, true)
+ of
+ {atomic, ok} -> Acc;
+ _ -> 1
+ end;
+ false -> Acc
+ end
+ end,
+ 0, Contacts);
+ false -> 404
end.
remove_contacts(U, S, Contacts) ->
case ejabberd_auth:is_user_exists(U, S) of
- true ->
- JID1 = jlib:jid_to_string({U, S, ""}),
- lists:foldl(fun(JID2, Acc) ->
- {PU, PS, _} = jlib:jid_tolower(jlib:string_to_jid(JID2)),
- case ejabberd_auth:is_user_exists(PU, PS) of
- true ->
- case unlink_contacts2(JID1, JID2, true) of
- {atomic, ok} -> Acc;
- _ -> 1
- end;
- false ->
- Acc
- end
- end, 0, Contacts);
- false ->
- 404
+ true ->
+ JID1 = jlib:jid_to_string({U, S, <<"">>}),
+ lists:foldl(fun (JID2, Acc) ->
+ {PU, PS, _} =
+ jlib:jid_tolower(jlib:string_to_jid(JID2)),
+ case ejabberd_auth:is_user_exists(PU, PS) of
+ true ->
+ case unlink_contacts2(JID1, JID2, true) of
+ {atomic, ok} -> Acc;
+ _ -> 1
+ end;
+ false -> Acc
+ end
+ end,
+ 0, Contacts);
+ false -> 404
end.
check_users_registration(Users) ->
- lists:map(fun({U, S}) ->
+ lists:map(fun ({U, S}) ->
Registered = case ejabberd_auth:is_user_exists(U, S) of
- true -> 1;
- false -> 0
+ true -> 1;
+ false -> 0
end,
{U, S, Registered}
- end, Users).
+ end,
+ Users).
%%%
%%% Groups of Roster Item
%%%
-add_rosteritem_groups(User, Server, JID, NewGroupsString, PushString) ->
+add_rosteritem_groups(User, Server, JID,
+ NewGroupsString, PushString) ->
{U1, S1, _} = jlib:jid_tolower(jlib:string_to_jid(JID)),
- NewGroups = string:tokens(NewGroupsString, ";"),
- Push = list_to_atom(PushString),
- case {ejabberd_auth:is_user_exists(U1, S1), ejabberd_auth:is_user_exists(User, Server)} of
- {true, true} ->
- case add_rosteritem_groups2(User, Server, JID, NewGroups, Push) of
- ok ->
- 0;
- Error ->
- ?INFO_MSG("Error found: ~n~p", [Error]),
- 1
- end;
- _ ->
- 404
+ NewGroups = str:tokens(NewGroupsString, <<";">>),
+ Push = jlib:binary_to_atom(PushString),
+ case {ejabberd_auth:is_user_exists(U1, S1),
+ ejabberd_auth:is_user_exists(User, Server)}
+ of
+ {true, true} ->
+ case add_rosteritem_groups2(User, Server, JID,
+ NewGroups, Push)
+ of
+ ok -> 0;
+ Error -> ?INFO_MSG("Error found: ~n~p", [Error]), 1
+ end;
+ _ -> 404
end.
-del_rosteritem_groups(User, Server, JID, NewGroupsString, PushString) ->
+del_rosteritem_groups(User, Server, JID,
+ NewGroupsString, PushString) ->
{U1, S1, _} = jlib:jid_tolower(jlib:string_to_jid(JID)),
- NewGroups = string:tokens(NewGroupsString, ";"),
- Push = list_to_atom(PushString),
- case {ejabberd_auth:is_user_exists(U1, S1), ejabberd_auth:is_user_exists(User, Server)} of
- {true, true} ->
- case del_rosteritem_groups2(User, Server, JID, NewGroups, Push) of
- ok ->
- 0;
- Error ->
- ?INFO_MSG("Error found: ~n~p", [Error]),
- 1
- end;
- _ ->
- 404
+ NewGroups = str:tokens(NewGroupsString, <<";">>),
+ Push = jlib:binary_to_atom(PushString),
+ case {ejabberd_auth:is_user_exists(U1, S1),
+ ejabberd_auth:is_user_exists(User, Server)}
+ of
+ {true, true} ->
+ case del_rosteritem_groups2(User, Server, JID,
+ NewGroups, Push)
+ of
+ ok -> 0;
+ Error -> ?INFO_MSG("Error found: ~n~p", [Error]), 1
+ end;
+ _ -> 404
end.
-modify_rosteritem_groups(User, Server, JID, NewGroupsString, SubsString, PushString) ->
- Nick = "", %% That information will not be used, anyway
- Subs = list_to_atom(SubsString),
- {U1, S1, _} = jlib:jid_tolower(jlib:string_to_jid(JID)),
- NewGroups = string:tokens(NewGroupsString, ";"),
- Push = list_to_atom(PushString),
+modify_rosteritem_groups(User, Server, JID,
+ NewGroupsString, SubsString, PushString) ->
+ Nick = <<"">>,
+ Subs = jlib:binary_to_atom(SubsString),
+ {_, _, _} = jlib:jid_tolower(jlib:string_to_jid(JID)),
+ NewGroups = str:tokens(NewGroupsString, <<";">>),
+ Push = jlib:binary_to_atom(PushString),
case ejabberd_auth:is_user_exists(User, Server) of
- true ->
- case modify_rosteritem_groups2(User, Server, JID, NewGroups, Push, Nick, Subs) of
- ok ->
- 0;
- Error ->
- ?INFO_MSG("Error found: ~n~p", [Error]),
- 1
- end;
- _ ->
- 404
+ true ->
+ case modify_rosteritem_groups2(User, Server, JID,
+ NewGroups, Push, Nick, Subs)
+ of
+ ok -> 0;
+ Error -> ?INFO_MSG("Error found: ~n~p", [Error]), 1
+ end;
+ _ -> 404
end.
-add_rosteritem_groups2(User, Server, JID, NewGroups, Push) ->
- GroupsFun =
- fun(Groups) ->
- lists:usort(NewGroups ++ Groups)
- end,
- change_rosteritem_group(User, Server, JID, GroupsFun, Push).
-
-del_rosteritem_groups2(User, Server, JID, NewGroups, Push) ->
- GroupsFun =
- fun(Groups) ->
- Groups -- NewGroups
- end,
- change_rosteritem_group(User, Server, JID, GroupsFun, Push).
-
-modify_rosteritem_groups2(User, Server, JID2, NewGroups, Push, Nick, Subs) when NewGroups == [] ->
- JID1 = jlib:jid_to_string(jlib:make_jid(User, Server, "")),
+add_rosteritem_groups2(User, Server, JID, NewGroups,
+ Push) ->
+ GroupsFun = fun (Groups) ->
+ lists:usort(NewGroups ++ Groups)
+ end,
+ change_rosteritem_group(User, Server, JID, GroupsFun,
+ Push).
+
+del_rosteritem_groups2(User, Server, JID, NewGroups,
+ Push) ->
+ GroupsFun = fun (Groups) -> Groups -- NewGroups end,
+ change_rosteritem_group(User, Server, JID, GroupsFun,
+ Push).
+
+modify_rosteritem_groups2(User, Server, JID2, NewGroups,
+ _Push, _Nick, _Subs)
+ when NewGroups == [] ->
+ JID1 = jlib:jid_to_string(jlib:make_jid(User, Server,
+ <<"">>)),
case unlink_contacts(JID1, JID2) of
- {atomic, ok} ->
- ok;
- Error ->
- Error
+ 0 -> ok;
+ Error -> Error
end;
-modify_rosteritem_groups2(User, Server, JID, NewGroups, Push, Nick, Subs) ->
- GroupsFun =
- fun(_Groups) ->
- NewGroups
- end,
- change_rosteritem_group(User, Server, JID, GroupsFun, Push, NewGroups, Nick, Subs).
-
-change_rosteritem_group(User, Server, JID, GroupsFun, Push) ->
- change_rosteritem_group(User, Server, JID, GroupsFun, Push, [], "", "both").
-
-change_rosteritem_group(User, Server, JID, GroupsFun, Push, NewGroups, Nick, Subs) ->
+modify_rosteritem_groups2(User, Server, JID, NewGroups,
+ Push, Nick, Subs) ->
+ GroupsFun = fun (_Groups) -> NewGroups end,
+ change_rosteritem_group(User, Server, JID, GroupsFun,
+ Push, NewGroups, Nick, Subs).
+
+change_rosteritem_group(User, Server, JID, GroupsFun,
+ Push) ->
+ change_rosteritem_group(User, Server, JID, GroupsFun,
+ Push, [], <<"">>, <<"both">>).
+
+change_rosteritem_group(User, Server, JID, GroupsFun,
+ Push, NewGroups, Nick, Subs) ->
{RU, RS, _} = jlib:jid_tolower(jlib:string_to_jid(JID)),
- LJID = {RU,RS,[]},
+ LJID = {RU, RS, <<>>},
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
- Result =
- case roster_backend(LServer) of
- mnesia ->
- mnesia:transaction(
- fun() ->
- case mnesia:read({roster, {LUser, LServer, LJID}}) of
- [#roster{} = Roster] ->
- NewGroups2 = GroupsFun(Roster#roster.groups),
- NewRoster = Roster#roster{groups = NewGroups2},
- mnesia:write(NewRoster),
- {ok, NewRoster#roster.name,
- NewRoster#roster.subscription,
- NewGroups2};
- _ ->
- not_in_roster
- end
- end);
- odbc ->
- ejabberd_odbc:sql_transaction(
- LServer,
- fun() ->
- Username = ejabberd_odbc:escape(User),
- SJID = ejabberd_odbc:escape(jlib:jid_to_string(LJID)),
- case ejabberd_odbc:sql_query_t(
- ["select nick, subscription from rosterusers "
- " where username='", Username, "' "
- " and jid='", SJID, "';"]) of
- {selected, ["nick", "subscription"],
- [{Name, SSubscription}]} ->
- Subscription =
- case SSubscription of
- "B" -> both;
- "T" -> to;
- "F" -> from;
- _ -> none
- end,
- Groups =
- case odbc_queries:get_roster_groups(
- LServer, Username, SJID) of
- {selected, ["grp"], JGrps}
- when is_list(JGrps) ->
- [JGrp || {JGrp} <- JGrps];
- _ ->
- []
- end,
- NewGroups2 = GroupsFun(Groups),
- ejabberd_odbc:sql_query_t(
- ["delete from rostergroups "
- " where username='", Username, "' "
- " and jid='", SJID, "';"]),
- lists:foreach(
- fun(Group) ->
- ejabberd_odbc:sql_query_t(
- ["insert into rostergroups("
- " username, jid, grp) "
- " values ('", Username, "',"
- "'", SJID, "',"
- "'", ejabberd_odbc:escape(Group), "');"])
- end,
- NewGroups2),
- {ok, Name, Subscription, NewGroups2};
- _ ->
- not_in_roster
- end
- end);
- none ->
- %% Apollo change: force roster push anyway with success
- {atomic, {ok, Nick, Subs, NewGroups}}
- end,
+ Result = case roster_backend(LServer) of
+ mnesia ->
+ mnesia:transaction(fun () ->
+ case mnesia:read({roster,
+ {LUser, LServer,
+ LJID}})
+ of
+ [#roster{} = Roster] ->
+ NewGroups2 =
+ GroupsFun(Roster#roster.groups),
+ NewRoster =
+ Roster#roster{groups =
+ NewGroups2},
+ mnesia:write(NewRoster),
+ {ok, NewRoster#roster.name,
+ NewRoster#roster.subscription,
+ NewGroups2};
+ _ -> not_in_roster
+ end
+ end);
+ odbc ->
+ ejabberd_odbc:sql_transaction(LServer,
+ fun () ->
+ Username =
+ ejabberd_odbc:escape(User),
+ SJID =
+ ejabberd_odbc:escape(jlib:jid_to_string(LJID)),
+ case
+ ejabberd_odbc:sql_query_t([<<"select nick, subscription from rosterusers "
+ " where username='">>,
+ Username,
+ <<"' and jid='">>,
+ SJID,
+ <<"';">>])
+ of
+ {selected,
+ [<<"nick">>,
+ <<"subscription">>],
+ [[Name,
+ SSubscription]]} ->
+ Subscription =
+ case
+ SSubscription
+ of
+ <<"B">> ->
+ both;
+ <<"T">> ->
+ to;
+ <<"F">> ->
+ from;
+ _ -> none
+ end,
+ Groups = case
+ odbc_queries:get_roster_groups(LServer,
+ Username,
+ SJID)
+ of
+ {selected,
+ [<<"grp">>],
+ JGrps}
+ when
+ is_list(JGrps) ->
+ [JGrp
+ || [JGrp]
+ <- JGrps];
+ _ ->
+ []
+ end,
+ NewGroups2 =
+ GroupsFun(Groups),
+ ejabberd_odbc:sql_query_t([<<"delete from rostergroups where "
+ "username='">>,
+ Username,
+ <<"' and jid='">>,
+ SJID,
+ <<"';">>]),
+ lists:foreach(fun
+ (Group) ->
+ ejabberd_odbc:sql_query_t([<<"insert into rostergroups( "
+ " username, jid, grp) values ('">>,
+ Username,
+ <<"','">>,
+ SJID,
+ <<"','">>,
+ ejabberd_odbc:escape(Group),
+ <<"');">>])
+ end,
+ NewGroups2),
+ {ok, Name,
+ Subscription,
+ NewGroups2};
+ _ -> not_in_roster
+ end
+ end);
+ none -> {atomic, {ok, Nick, Subs, NewGroups}}
+ end,
case {Result, Push} of
- {{atomic, {ok, Name, Subscription, NewGroups3}}, true} ->
- roster_push(User, Server, JID,
- Name, atom_to_list(Subscription), NewGroups3),
- ok;
- {{atomic, {ok, _Name, _Subscription, _NewGroups3}}, false} -> ok;
- {{atomic, not_in_roster}, _} -> not_in_roster;
- Error -> {error, Error}
- end.
-
-%%%
-%%% PubSub
-%%%
-
-update_status(JidString, NodeString, Itemid, PayloadString) ->
- Publisher = jlib:string_to_jid(JidString),
- Host = jlib:jid_tolower(jlib:jid_remove_resource(Publisher)),
- ServerHost = Publisher#jid.lserver,
- Node = mod_pubsub_on:string_to_node(NodeString),
- Payload = [xml_stream:parse_element(PayloadString)],
- ?DEBUG("PayloadString: ~n~p~nPayload elements: ~n~p", [PayloadString, Payload]),
- case mod_pubsub_on:publish_item_nothook(Host, ServerHost, Node, Publisher, Itemid, Payload) of
- {result, _} ->
- "OK";
- {error, {xmlelement, _, _, _} = XmlEl} ->
- "ERROR: " ++ xml:element_to_string(XmlEl);
- {error, ErrorAtom} when is_atom(ErrorAtom) ->
- "ERROR: " ++ atom_to_list(ErrorAtom);
- {error, ErrorString} when is_list(ErrorString) ->
- "ERROR: " ++ ErrorString
- end.
-
-delete_status(JidString, NodeString, Itemid) ->
- Publisher = jlib:string_to_jid(JidString),
- Host = jlib:jid_tolower(jlib:jid_remove_resource(Publisher)),
- Node = mod_pubsub_on:string_to_node(NodeString),
- case mod_pubsub_on:delete_item_nothook(Host, Node, Publisher, Itemid, true) of
- {result, _} ->
- "OK";
- {error, {xmlelement, _, _, _} = XmlEl} ->
- "ERROR: " ++ xml:element_to_string(XmlEl);
- {error, ErrorAtom} when is_atom(ErrorAtom) ->
- "ERROR: " ++ atom_to_list(ErrorAtom);
- {error, ErrorString} when is_list(ErrorString) ->
- "ERROR: " ++ ErrorString
+ {{atomic, {ok, Name, Subscription, NewGroups3}},
+ true} ->
+ roster_push(User, Server, JID, Name,
+ iolist_to_binary(atom_to_list(Subscription)),
+ NewGroups3),
+ ok;
+ {{atomic, {ok, _Name, _Subscription, _NewGroups3}},
+ false} ->
+ ok;
+ {{atomic, not_in_roster}, _} -> not_in_roster;
+ Error -> {error, Error}
end.
-transport_register(Host, TransportString, JIDString, Username, Password) ->
- TransportAtom = list_to_atom(TransportString),
- case {lists:member(Host, ?MYHOSTS), jlib:string_to_jid(JIDString)} of
- {true, JID} when is_record(JID, jid) ->
- case catch gen_transport:register(Host, TransportAtom, JIDString,
- Username, Password) of
- ok ->
- "OK";
- {error, Reason} ->
- "ERROR: " ++ atom_to_list(Reason);
- {'EXIT', {timeout,_}} ->
- "ERROR: timed_out";
- {'EXIT', _} ->
- "ERROR: unexpected_error"
- end;
- {false, _} ->
- "ERROR: unknown_host";
- _ ->
- "ERROR: bad_jid"
+transport_register(Host, TransportString, JIDString,
+ Username, Password) ->
+ TransportAtom = jlib:binary_to_atom(TransportString),
+ case {lists:member(Host, ?MYHOSTS),
+ jlib:string_to_jid(JIDString)}
+ of
+ {true, JID} when is_record(JID, jid) ->
+ case catch apply(gen_transport, register, [Host, TransportAtom,
+ JIDString, Username, Password])
+ of
+ ok -> <<"OK">>;
+ {error, Reason} ->
+ <<"ERROR: ",
+ (iolist_to_binary(atom_to_list(Reason)))/binary>>;
+ {'EXIT', {timeout, _}} -> <<"ERROR: timed_out">>;
+ {'EXIT', _} -> <<"ERROR: unexpected_error">>
+ end;
+ {false, _} -> <<"ERROR: unknown_host">>;
+ _ -> <<"ERROR: bad_jid">>
end.
%%%
@@ -956,33 +936,41 @@ transport_register(Host, TransportString, JIDString, Username, Password) ->
send_chat(FromJID, ToJID, Msg) ->
From = jlib:string_to_jid(FromJID),
To = jlib:string_to_jid(ToJID),
- Stanza = {xmlelement, "message", [{"type", "chat"}],
- [{xmlelement, "body", [], [{xmlcdata, Msg}]}]},
+ Stanza = #xmlel{name = <<"message">>,
+ attrs = [{<<"type">>, <<"chat">>}],
+ children =
+ [#xmlel{name = <<"body">>, attrs = [],
+ children = [{xmlcdata, Msg}]}]},
ejabberd_router:route(From, To, Stanza),
0.
send_message(FromJID, ToJID, Sub, Msg) ->
From = jlib:string_to_jid(FromJID),
To = jlib:string_to_jid(ToJID),
- Stanza = {xmlelement, "message", [{"type", "normal"}],
- [{xmlelement, "subject", [], [{xmlcdata, Sub}]},
- {xmlelement, "body", [], [{xmlcdata, Msg}]}]},
+ Stanza = #xmlel{name = <<"message">>,
+ attrs = [{<<"type">>, <<"normal">>}],
+ children =
+ [#xmlel{name = <<"subject">>, attrs = [],
+ children = [{xmlcdata, Sub}]},
+ #xmlel{name = <<"body">>, attrs = [],
+ children = [{xmlcdata, Msg}]}]},
ejabberd_router:route(From, To, Stanza),
0.
send_stanza(FromJID, ToJID, StanzaStr) ->
case xml_stream:parse_element(StanzaStr) of
- {error, _} ->
- 1;
- Stanza ->
- {xmlelement, _, Attrs, _} = Stanza,
- From = jlib:string_to_jid(proplists:get_value("from", Attrs, FromJID)),
- To = jlib:string_to_jid(proplists:get_value("to", Attrs, ToJID)),
- ejabberd_router:route(From, To, Stanza),
- 0
+ {error, _} -> 1;
+ Stanza ->
+ #xmlel{attrs = Attrs} = Stanza,
+ From =
+ jlib:string_to_jid(proplists:get_value(<<"from">>,
+ Attrs, FromJID)),
+ To = jlib:string_to_jid(proplists:get_value(<<"to">>,
+ Attrs, ToJID)),
+ ejabberd_router:route(From, To, Stanza),
+ 0
end.
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Internal functions
@@ -993,71 +981,79 @@ send_stanza(FromJID, ToJID, StanzaStr) ->
get_roster2(User, Server) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
- case roster_backend(LServer) of
- mnesia -> mod_roster:get_user_roster([], {LUser, LServer});
- odbc -> mod_roster_odbc:get_user_roster([], {LUser, LServer})
- end.
+ mod_roster:get_user_roster([], {LUser, LServer}).
-add_rosteritem2(User, Server, JID, Nick, Group, Subscription, Push) ->
+add_rosteritem2(User, Server, JID, Nick, Group,
+ Subscription, Push) ->
{RU, RS, _} = jlib:jid_tolower(jlib:string_to_jid(JID)),
- LJID = {RU,RS,[]},
+ LJID = {RU, RS, <<>>},
Groups = case Group of
- [] -> [];
- _ -> [Group]
+ [] -> [];
+ _ -> [Group]
+ end,
+ Roster = #roster{usj = {User, Server, LJID},
+ us = {User, Server}, jid = LJID, name = Nick,
+ ask = none,
+ subscription = jlib:binary_to_atom(Subscription),
+ groups = Groups},
+ Result = case roster_backend(Server) of
+ mnesia ->
+ mnesia:transaction(fun () ->
+ case mnesia:read({roster,
+ {User, Server,
+ LJID}})
+ of
+ [#roster{subscription =
+ both}] ->
+ already_added;
+ _ -> mnesia:write(Roster)
+ end
+ end);
+ odbc ->
+ case ejabberd_odbc:sql_transaction(Server,
+ fun () ->
+ Username =
+ ejabberd_odbc:escape(User),
+ SJID =
+ ejabberd_odbc:escape(jlib:jid_to_string(LJID)),
+ case
+ ejabberd_odbc:sql_query_t([<<"select username from rosterusers "
+ " where username='">>,
+ Username,
+ <<"' and jid='">>,
+ SJID,
+ <<"' and subscription = 'B';">>])
+ of
+ {selected,
+ [<<"username">>],
+ []} ->
+ ItemVals =
+ mod_roster:record_to_string(Roster),
+ ItemGroups =
+ mod_roster:groups_to_string(Roster),
+ ejabberd_odbc:sql_query_t(odbc_queries:update_roster_sql(Username,
+ SJID,
+ ItemVals,
+ ItemGroups));
+ _ ->
+ already_added
+ end
+ end)
+ of
+ {atomic, already_added} -> {atomic, already_added};
+ {atomic, _} -> {atomic, ok};
+ Error -> Error
+ end;
+ none -> {atomic, ok}
end,
- Roster = #roster{
- usj = {User,Server,LJID},
- us = {User,Server},
- jid = LJID,
- name = Nick,
- ask = none,
- subscription = list_to_atom(Subscription),
- groups = Groups},
- Result =
- case roster_backend(Server) of
- mnesia ->
- mnesia:transaction(fun() ->
- case mnesia:read({roster,{User,Server,LJID}}) of
- [#roster{subscription=both}] ->
- already_added;
- _ ->
- mnesia:write(Roster)
- end
- end);
- odbc ->
- %% MREMOND: TODO: check if already_added
- case ejabberd_odbc:sql_transaction(Server,
- fun() ->
- Username = ejabberd_odbc:escape(User),
- SJID = ejabberd_odbc:escape(jlib:jid_to_string(LJID)),
- case ejabberd_odbc:sql_query_t(
- ["select username from rosterusers "
- " where username='", Username, "' "
- " and jid='", SJID,
- "' and subscription = 'B';"]) of
- {selected, ["username"],[]} ->
- ItemVals = record_to_string(Roster),
- ItemGroups = groups_to_string(Roster),
- ejabberd_odbc:sql_query_t(
- odbc_queries:update_roster_sql(
- Username, SJID, ItemVals, ItemGroups));
- _ ->
- already_added
- end
- end) of
- {atomic, already_added} -> {atomic, already_added};
- {atomic, _} -> {atomic, ok};
- Error -> Error
- end;
- none ->
- %% If no known mod_roster is enabled, still let the code to proceed
- {atomic, ok}
- end,
case {Result, Push} of
- {{atomic, already_added}, _} -> ok; %% No need for roster push
- {{atomic, ok}, true} -> roster_push(User, Server, JID, Nick, Subscription, Groups);
- {{atomic, ok}, false} -> ok;
- _ -> error
+ {{atomic, already_added}, _} ->
+ ok; %% No need for roster push
+ {{atomic, ok}, true} ->
+ roster_push(User, Server, JID, Nick, Subscription,
+ Groups);
+ {{atomic, ok}, false} -> ok;
+ _ -> error
end,
Result.
@@ -1066,282 +1062,239 @@ del_rosteritem(User, Server, JID) ->
del_rosteritem(User, Server, JID, Push) ->
{RU, RS, _} = jlib:jid_tolower(jlib:string_to_jid(JID)),
- LJID = {RU,RS,[]},
+ LJID = {RU, RS, <<>>},
Result = case roster_backend(Server) of
- mnesia ->
- mnesia:transaction(fun() ->
- mnesia:delete({roster, {User,Server,LJID}})
- end);
- odbc ->
- case ejabberd_odbc:sql_transaction(Server, fun() ->
- Username = ejabberd_odbc:escape(User),
- SJID = ejabberd_odbc:escape(jlib:jid_to_string(LJID)),
- odbc_queries:del_roster(Server, Username, SJID)
- end) of
- {atomic, _} -> {atomic, ok};
- Error -> Error
- end;
- none ->
- %% If no known mod_roster is enabled, still let the code to proceed
- {atomic, ok}
+ mnesia ->
+ mnesia:transaction(fun () ->
+ mnesia:delete({roster,
+ {User, Server,
+ LJID}})
+ end);
+ odbc ->
+ case ejabberd_odbc:sql_transaction(Server,
+ fun () ->
+ Username =
+ ejabberd_odbc:escape(User),
+ SJID =
+ ejabberd_odbc:escape(jlib:jid_to_string(LJID)),
+ odbc_queries:del_roster(Server,
+ Username,
+ SJID)
+ end)
+ of
+ {atomic, _} -> {atomic, ok};
+ Error -> Error
+ end;
+ none -> {atomic, ok}
end,
case {Result, Push} of
- {{atomic, ok}, true} -> roster_push(User, Server, JID, "", "remove", []);
- {{atomic, ok}, false} -> ok;
- _ -> error
+ {{atomic, ok}, true} ->
+ roster_push(User, Server, JID, <<"">>, <<"remove">>,
+ []);
+ {{atomic, ok}, false} -> ok;
+ _ -> error
end,
Result.
-link_contacts2(JID1, Nick1, Group1, JID2, Nick2, Group2, Push) ->
- {U1, S1, _} = jlib:jid_tolower(jlib:string_to_jid(JID1)),
- {U2, S2, _} = jlib:jid_tolower(jlib:string_to_jid(JID2)),
- case add_rosteritem2(U1, S1, JID2, Nick2, Group1, "both", Push) of
- {atomic, ok} -> add_rosteritem2(U2, S2, JID1, Nick1, Group2, "both", Push);
- Error -> Error
+link_contacts2(JID1, Nick1, Group1, JID2, Nick2, Group2,
+ Push) ->
+ {U1, S1, _} =
+ jlib:jid_tolower(jlib:string_to_jid(JID1)),
+ {U2, S2, _} =
+ jlib:jid_tolower(jlib:string_to_jid(JID2)),
+ case add_rosteritem2(U1, S1, JID2, Nick2, Group1,
+ <<"both">>, Push)
+ of
+ {atomic, ok} ->
+ add_rosteritem2(U2, S2, JID1, Nick1, Group2, <<"both">>,
+ Push);
+ Error -> Error
end.
unlink_contacts2(JID1, JID2, Push) ->
- {U1, S1, _} = jlib:jid_tolower(jlib:string_to_jid(JID1)),
- {U2, S2, _} = jlib:jid_tolower(jlib:string_to_jid(JID2)),
+ {U1, S1, _} =
+ jlib:jid_tolower(jlib:string_to_jid(JID1)),
+ {U2, S2, _} =
+ jlib:jid_tolower(jlib:string_to_jid(JID2)),
case del_rosteritem(U1, S1, JID2, Push) of
- {atomic, ok} -> del_rosteritem(U2, S2, JID1, Push);
- Error -> Error
+ {atomic, ok} -> del_rosteritem(U2, S2, JID1, Push);
+ Error -> Error
end.
-roster_push(User, Server, JID, Nick, Subscription, Groups) ->
- LJID = jlib:make_jid(User, Server, ""),
+roster_push(User, Server, JID, Nick, Subscription,
+ Groups) ->
TJID = jlib:string_to_jid(JID),
{TU, TS, _} = jlib:jid_tolower(TJID),
- Presence =
- {xmlelement, "presence",
- [{"type",
- case Subscription of
- "remove" -> "unsubscribed";
- "none" -> "unsubscribe";
- "both" -> "subscribed";
- _ -> "subscribe"
- end}], []},
- ItemAttrs =
- case Nick of
- "" -> [{"jid", JID}, {"subscription", Subscription}];
- _ -> [{"jid", JID}, {"name", Nick}, {"subscription", Subscription}]
- end,
- ItemGroups =
- lists:map(fun(G) ->
- {xmlelement, "group", [], [{xmlcdata, G}]}
- end, Groups),
- Result =
- jlib:iq_to_xml(
- #iq{type = set, xmlns = ?NS_ROSTER, id = "push",
- lang = "langxmlrpc-en",
- sub_el = [{xmlelement, "query", [{"xmlns", ?NS_ROSTER}],
- [{xmlelement, "item", ItemAttrs, ItemGroups}]}]}),
- %% ejabberd_router:route(TJID, LJID, Presence),
- %% ejabberd_router:route(LJID, LJID, Result),
- lists:foreach(
- fun(Resource) ->
- UJID = jlib:make_jid(User, Server, Resource),
- ejabberd_router:route(TJID, UJID, Presence),
- ejabberd_router:route(UJID, UJID, Result),
- case Subscription of
- "remove" -> none;
- _ ->
- lists:foreach(
- fun(TR) ->
- ejabberd_router:route(
- jlib:make_jid(TU, TS, TR), UJID,
- {xmlelement, "presence", [], []})
- end, get_resources(TU, TS))
- end
- end, [R || R <- get_resources(User, Server)]).
+ Presence = #xmlel{name = <<"presence">>,
+ attrs =
+ [{<<"type">>,
+ case Subscription of
+ <<"remove">> -> <<"unsubscribed">>;
+ <<"none">> -> <<"unsubscribe">>;
+ <<"both">> -> <<"subscribed">>;
+ _ -> <<"subscribe">>
+ end}],
+ children = []},
+ ItemAttrs = case Nick of
+ <<"">> ->
+ [{<<"jid">>, JID}, {<<"subscription">>, Subscription}];
+ _ ->
+ [{<<"jid">>, JID}, {<<"name">>, Nick},
+ {<<"subscription">>, Subscription}]
+ end,
+ ItemGroups = lists:map(fun (G) ->
+ #xmlel{name = <<"group">>, attrs = [],
+ children = [{xmlcdata, G}]}
+ end,
+ Groups),
+ Result = jlib:iq_to_xml(#iq{type = set,
+ xmlns = ?NS_ROSTER, id = <<"push">>,
+ lang = <<"langxmlrpc-en">>,
+ sub_el =
+ [#xmlel{name = <<"query">>,
+ attrs = [{<<"xmlns">>, ?NS_ROSTER}],
+ children =
+ [#xmlel{name = <<"item">>,
+ attrs = ItemAttrs,
+ children =
+ ItemGroups}]}]}),
+ lists:foreach(fun (Resource) ->
+ UJID = jlib:make_jid(User, Server, Resource),
+ ejabberd_router:route(TJID, UJID, Presence),
+ ejabberd_router:route(UJID, UJID, Result),
+ case Subscription of
+ <<"remove">> -> none;
+ _ ->
+ lists:foreach(fun (TR) ->
+ ejabberd_router:route(jlib:make_jid(TU,
+ TS,
+ TR),
+ UJID,
+ #xmlel{name
+ =
+ <<"presence">>,
+ attrs
+ =
+ [],
+ children
+ =
+ []})
+ end,
+ get_resources(TU, TS))
+ end
+ end,
+ [R || R <- get_resources(User, Server)]).
roster_backend(Server) ->
Modules = gen_mod:loaded_modules(Server),
Mnesia = lists:member(mod_roster, Modules),
Odbc = lists:member(mod_roster_odbc, Modules),
if Mnesia -> mnesia;
- true ->
- if Odbc -> odbc;
- true -> none
- end
+ true ->
+ if Odbc -> odbc;
+ true -> none
+ end
end.
-record_to_string(#roster{us = {User, _Server},
- jid = JID,
- name = Name,
- subscription = Subscription,
- ask = Ask,
- askmessage = AskMessage}) ->
- Username = ejabberd_odbc:escape(User),
- SJID = ejabberd_odbc:escape(jlib:jid_to_string(jlib:jid_tolower(JID))),
- Nick = ejabberd_odbc:escape(Name),
- SSubscription = case Subscription of
- both -> "B";
- to -> "T";
- from -> "F";
- none -> "N"
- end,
- SAsk = case Ask of
- subscribe -> "S";
- unsubscribe -> "U";
- both -> "B";
- out -> "O";
- in -> "I";
- none -> "N"
- end,
- SAskMessage = ejabberd_odbc:escape(AskMessage),
- ["'", Username, "',"
- "'", SJID, "',"
- "'", Nick, "',"
- "'", SSubscription, "',"
- "'", SAsk, "',"
- "'", SAskMessage, "',"
- "'N', '', 'item'"].
-
-groups_to_string(#roster{us = {User, _Server},
- jid = JID,
- groups = Groups}) ->
- Username = ejabberd_odbc:escape(User),
- SJID = ejabberd_odbc:escape(jlib:jid_to_string(jlib:jid_tolower(JID))),
- %% Empty groups do not need to be converted to string to be inserted in
- %% the database
- lists:foldl(fun([], Acc) -> Acc;
- (Group, Acc) ->
- String = ["'", Username, "',"
- "'", SJID, "',"
- "'", ejabberd_odbc:escape(Group), "'"],
- [String|Acc]
- end, [], Groups).
-
-%% Format roster items as a list of:
-%% [{struct, [{jid, "test@localhost"},{group, "Friends"},{nick, "Nicktest"}]}]
-format_roster([]) ->
- [];
-format_roster(Items) ->
- format_roster(Items, []).
-format_roster([], Structs) ->
- Structs;
-format_roster([#roster{jid=JID, name=Nick, groups=Group,
- subscription=Subs, ask=Ask}|Items], Structs) ->
- {User,Server,_Resource} = JID,
- Struct = {lists:flatten([User,"@",Server]),
- Group,
- Nick,
- atom_to_list(Subs),
- atom_to_list(Ask)
- },
- format_roster(Items, [Struct|Structs]).
-
-%% Note: If user is connected several times, only keep the resource with the
-%% highest non-negative priority
-format_roster_with_presence([]) ->
- [];
+format_roster([]) -> [];
+format_roster(Items) -> format_roster(Items, []).
+
+format_roster([], Structs) -> Structs;
+format_roster([#roster{jid = JID, name = Nick,
+ groups = Group, subscription = Subs, ask = Ask}
+ | Items],
+ Structs) ->
+ {User, Server, _Resource} = JID,
+ Struct = {lists:flatten([User, <<"@">>, Server]), Group,
+ Nick, iolist_to_binary(atom_to_list(Subs)),
+ iolist_to_binary(atom_to_list(Ask))},
+ format_roster(Items, [Struct | Structs]).
+
+format_roster_with_presence([]) -> [];
format_roster_with_presence(Items) ->
format_roster_with_presence(Items, []).
-format_roster_with_presence([], Structs) ->
- Structs;
-format_roster_with_presence([#roster{jid=JID, name=Nick, groups=Group,
- subscription=Subs, ask=Ask}|Items], Structs) ->
- {User,Server,_R} = JID,
+
+format_roster_with_presence([], Structs) -> Structs;
+format_roster_with_presence([#roster{jid = JID,
+ name = Nick, groups = Group,
+ subscription = Subs, ask = Ask}
+ | Items],
+ Structs) ->
+ {User, Server, _R} = JID,
Presence = case Subs of
- both -> get_presence2(User, Server);
- from -> get_presence2(User, Server);
- _Other -> {"", "unavailable", ""}
+ both -> get_presence2(User, Server);
+ from -> get_presence2(User, Server);
+ _Other -> {<<"">>, <<"unavailable">>, <<"">>}
end,
- {Resource, Show, Status} =
- case Presence of
- {_R, "invisible", _S} -> {"", "unavailable", ""};
- _Status -> Presence
- end,
- Struct = {lists:flatten([User,"@",Server]),
- Resource,
- extract_group(Group),
- Nick,
- atom_to_list(Subs),
- atom_to_list(Ask),
- Show,
- Status
- },
- format_roster_with_presence(Items, [Struct|Structs]).
+ {Resource, Show, Status} = Presence,
+ Struct = {lists:flatten([User, <<"@">>, Server]),
+ Resource, extract_group(Group), Nick,
+ iolist_to_binary(atom_to_list(Subs)),
+ iolist_to_binary(atom_to_list(Ask)), Show, Status},
+ format_roster_with_presence(Items, [Struct | Structs]).
extract_group([]) -> [];
%extract_group([Group|_Groups]) -> Group.
-extract_group(Groups) -> string:join(Groups, ";").
-
-extract_groups([]) -> [];
-%extract_groups([Group|_Groups]) -> Group.
-extract_groups(Groups) -> {list, Groups}.
+extract_group(Groups) -> str:join(Groups, <<";">>).
%% -----------------------------
%% Internal session handling
%% -----------------------------
-%% This is inspired from ejabberd_sm.erl
get_presence2(User, Server) ->
case get_sessions(User, Server) of
- [] ->
- {"", "unavailable", ""};
- Ss ->
- Session = hd(Ss),
- if Session#session.priority >= 0 ->
- Pid = element(2, Session#session.sid),
- %{_User, _Resource, Show, Status} = rpc:call(node(Pid), ejabberd_c2s, get_presence, [Pid]),
- {_User, Resource, Show, Status} = ejabberd_c2s:get_presence(Pid),
- {Resource, Show, Status};
- true ->
- {"", "unavailable", ""}
- end
+ [] -> {<<"">>, <<"unavailable">>, <<"">>};
+ Ss ->
+ Session = hd(Ss),
+ if Session#session.priority >= 0 ->
+ Pid = element(2, Session#session.sid),
+ {_User, Resource, Show, Status} =
+ ejabberd_c2s:get_presence(Pid),
+ {Resource, Show, Status};
+ true -> {<<"">>, <<"unavailable">>, <<"">>}
+ end
end.
get_resources2(User, Server) ->
- lists:map(fun(S) -> element(3, S#session.usr)
- end, get_sessions(User, Server)).
+ lists:map(fun (S) -> element(3, S#session.usr) end,
+ get_sessions(User, Server)).
get_sessions(User, Server) ->
US = {jlib:nodeprep(User), jlib:nameprep(Server)},
Node = ejabberd_cluster:get_node(US),
case catch rpc:call(Node, mnesia, dirty_index_read,
- [session, US, #session.us], 5000) of
- Result when is_list(Result), Result /= [] ->
- lists:reverse(lists:keysort(#session.priority, clean_session_list(Result)));
- _ ->
- []
+ [session, US, #session.us], 5000)
+ of
+ Result when is_list(Result), Result /= [] ->
+ lists:reverse(lists:keysort(#session.priority,
+ clean_session_list(Result)));
+ _ -> []
end.
clean_session_list(Ss) ->
clean_session_list(lists:keysort(#session.usr, Ss), []).
-clean_session_list([], Res) ->
- Res;
-clean_session_list([S], Res) ->
- [S | Res];
+clean_session_list([], Res) -> Res;
+clean_session_list([S], Res) -> [S | Res];
clean_session_list([S1, S2 | Rest], Res) ->
- if
- S1#session.usr == S2#session.usr ->
- if
- S1#session.sid > S2#session.sid ->
- clean_session_list([S1 | Rest], Res);
- true ->
- clean_session_list([S2 | Rest], Res)
- end;
- true ->
- clean_session_list([S2 | Rest], [S1 | Res])
+ if S1#session.usr == S2#session.usr ->
+ if S1#session.sid > S2#session.sid ->
+ clean_session_list([S1 | Rest], Res);
+ true -> clean_session_list([S2 | Rest], Res)
+ end;
+ true -> clean_session_list([S2 | Rest], [S1 | Res])
end.
-
%% -----------------------------
%% Internal function pattern
%% -----------------------------
user_action(User, Server, Fun, OK) ->
case ejabberd_auth:is_user_exists(User, Server) of
- true ->
- case catch Fun() of
- OK ->
- 0;
- _ ->
- 1
- end;
- false ->
- 404
+ true ->
+ case catch Fun() of
+ OK -> 0;
+ _ -> 1
+ end;
+ false -> 404
end.