Module ejabberd_commands [erl svg]

Management of ejabberd commands.

To do

Description

Management of ejabberd commands.

An ejabberd command is an abstract function identified by a name, with a defined number and type of calling arguments and type of result, that can be defined in any Erlang module and executed using any valid frontend.

Define a new ejabberd command

ejabberd commands can be defined and registered in any Erlang module.

Some commands are procedures; and their purpose is to perform an action in the server, so the command result is only some result code or result tuple. Other commands are inspectors, and their purpose is to gather some information about the server and return a detailed response: it can be integer, string, atom, tuple, list or a mix of those ones.

The arguments and result of an ejabberd command are strictly defined. The number and format of the arguments provided when calling an ejabberd command must match the definition of that command. The format of the result provided by an ejabberd command must be exactly its definition. For example, if a command is said to return an integer, it must always return an integer (except in case of a crash).

If you are developing an Erlang module that will run inside ejabberd and you want to provide a new ejabberd command to administer some task related to your module, you only need to: implement a function, define the command, and register it.

Define a new ejabberd command

An ejabberd command is defined using the Erlang record 'ejabberd_commands'. This record has several elements that you must define. Note that 'tags', 'desc' and 'longdesc' are optional.

For example let's define an ejabberd command 'pow' that gets the integers 'base' and 'exponent'. Its result will be an integer 'power':

#ejabberd_commands{name = pow, tags = [test],
                   desc = "Return the power of base for exponent",
                   longdesc = "This is an example command. The formula is:\n"
                   "  power = base ^ exponent",
                   module = ?MODULE, function = pow,
                   args = [{base, integer}, {exponent, integer}],
                   result = {power, integer}}

Implement the function associated to the command

Now implement a function in your module that matches the arguments and result of the ejabberd command.

For example the function calc_power gets two integers Base and Exponent. It calculates the power and rounds to an integer:

calc_power(Base, Exponent) ->
      PowFloat = math:pow(Base, Exponent),
      round(PowFloat).
Since this function will be called by ejabberd_commands, it must be exported. Add to your module:
-export([calc_power/2]).

Only some types of result formats are allowed. If the format is defined as 'rescode', then your function must return: ok | true | atom() where the atoms ok and true as considered positive answers, and any other response atom is considered negative.

If the format is defined as 'restuple', then the command must return: {rescode(), string()}

If the format is defined as '{list, something()}', then the command must return a list of something().

Register the command

Define this function and put inside the #ejabberd_command you defined in the beginning:

commands() ->
      [
  
      ].

You need to include this header file in order to use the record:

-include("ejabberd_commands.hrl").

When your module is initialized or started, register your commands:

ejabberd_commands:register_commands(commands()),

And when your module is stopped, unregister your commands:

ejabberd_commands:unregister_commands(commands()),

That's all! Now when your module is started, the command will be registered and any frontend can access it. For example:

$ ejabberdctl help pow
  
     Command Name: pow
  
     Arguments: base::integer
                exponent::integer
  
     Returns: power::integer
  
     Tags: test
  
     Description: Return the power of base for exponent
  
   This is an example command. The formula is:
    power = base ^ exponent
  
   $ ejabberdctl pow 3 4
   81
   

Execute an ejabberd command

ejabberd commands are mean to be executed using any valid frontend. An ejabberd commands is implemented in a regular Erlang function, so it is also possible to execute this function in any Erlang module, without dealing with the associated ejabberd commands.

Frontend to ejabberd commands

Currently there are two frontends to ejabberd commands: the shell script ejabberdctl, and the XML-RPC server ejabberd_xmlrpc.

ejabberdctl as a frontend to ejabberd commands

It is possible to use ejabberdctl to get documentation of any command. But ejabberdctl does not support all the argument types allowed in ejabberd commands, so there are some ejabberd commands that cannot be executed using ejabberdctl.

Also note that the ejabberdctl shell administration script also manages ejabberdctl commands, which are unrelated to ejabberd commands and can only be executed using ejabberdctl.

ejabberd_xmlrpc as a frontend to ejabberd commands

ejabberd_xmlrpc provides an XML-RPC server to execute ejabberd commands. ejabberd_xmlrpc is a contributed module published in ejabberd-modules SVN.

Since ejabberd_xmlrpc does not provide any method to get documentation of the ejabberd commands, please use ejabberdctl to know which commands are available, and their usage.

The number and format of the arguments provided when calling an ejabberd command must match the definition of that command. Please make sure the XML-RPC call provides the required arguments, with the specified format. The order of the arguments in an XML-RPC call is not important, because all the data is tagged and will be correctly prepared by ejabberd_xmlrpc before executing the ejabberd command.

Data Types

aterm()

aterm() = {Name::atom(), Type::atype()}

An argument term is a tuple with the term name and the term type.

atype()

atype() = integer | string | {tuple, [aterm()]} | {list, aterm()}

Allowed types for arguments are integer, string, tuple and list.

ejabberd_commands()

ejabberd_commands() = #ejabberd_commands{name = atom(), tags = [atom()], desc = string(), longdesc = string(), module = atom(), function = atom(), args = [aterm()], result = rterm()}

desc: Description of the command args: Describe the accepted arguments. This way the function that calls the command can format the arguments before calling.

rterm()

rterm() = {Name::atom(), Type::rtype()}

A result term is a tuple with the term name and the term type.

rtype()

rtype() = integer | string | atom | {tuple, [rterm()]} | {list, rterm()} | rescode | restuple

A rtype is either an atom or a tuple with two elements.

Function Index

check_access/2*
check_access_arguments/3*
check_access_command/5*
check_access_commands/5*Check access is allowed to that command.
check_auth/1*
execute_command/2Execute a command.
execute_command/4
execute_command2/2*
get_command_definition/1Get the definition record of a command.
get_command_format/1Get the format of arguments and result of a command.
get_md5/1*
get_tags_commands/0Get all the tags and associated commands.
init/0
list_commands/0Get a list of all the available commands, arguments and description.
register_commands/1Register ejabberd commands.
tag_arguments/2*
unregister_commands/1Unregister ejabberd commands.

Function Details

check_access/2 *

check_access(Access, Auth) -> any()

check_access_arguments/3 *

check_access_arguments(Command, ArgumentRestrictions, Arguments) -> any()

check_access_command/5 *

check_access_command(Commands, Command, ArgumentRestrictions, Method, Arguments) -> any()

check_access_commands/5 *

check_access_commands(AccessCommands, Auth, Method, Command, Arguments) -> ok

Check access is allowed to that command. At least one AccessCommand must be satisfied. It may throw {error, Error} where: Error = account_unprivileged | invalid_account_data

check_auth/1 *

check_auth(X1) -> any()

execute_command/2

execute_command(Name::atom(), Arguments) -> ResultTerm | {error, command_unknown}

Execute a command.

execute_command/4

execute_command(AccessCommands, Auth, Name::atom(), Arguments) -> ResultTerm | {error, Error}

execute_command2/2 *

execute_command2(Command, Arguments) -> any()

get_command_definition/1

get_command_definition(Name::atom()) -> ejabberd_commands() | command_not_found

Get the definition record of a command.

get_command_format/1

get_command_format(Name::atom()) -> {Args::[aterm()], Result::rterm()} | {error, command_unknown}

Get the format of arguments and result of a command.

get_md5/1 *

get_md5(AccountPass) -> any()

get_tags_commands/0

get_tags_commands() -> [{Tag::string(), [CommandName::string()]}]

Get all the tags and associated commands.

init/0

init() -> any()

list_commands/0

list_commands() -> [{Name::atom(), Args::[aterm()], Desc::string()}]

Get a list of all the available commands, arguments and description.

register_commands/1

register_commands(Commands::[ejabberd_commands()]) -> ok

Register ejabberd commands. If a command is already registered, a warning is printed and the old command is preserved.

tag_arguments/2 *

tag_arguments(ArgsDefs, Args) -> any()

unregister_commands/1

unregister_commands(Commands::[ejabberd_commands()]) -> ok

Unregister ejabberd commands.


Generated by EDoc, May 23 2012, 07:15:17.