aboutsummaryrefslogtreecommitdiff
path: root/ejabberdctl.template
diff options
context:
space:
mode:
Diffstat (limited to 'ejabberdctl.template')
-rwxr-xr-xejabberdctl.template472
1 files changed, 170 insertions, 302 deletions
diff --git a/ejabberdctl.template b/ejabberdctl.template
index 5b34ebee4..a940c3df7 100755
--- a/ejabberdctl.template
+++ b/ejabberdctl.template
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
# define default configuration
POLL=true
@@ -7,138 +7,92 @@ ERL_MAX_PORTS=32000
ERL_PROCESSES=250000
ERL_MAX_ETS_TABLES=1400
FIREWALL_WINDOW=""
+INET_DIST_INTERFACE=""
ERLANG_NODE=ejabberd@localhost
# define default environment variables
-SCRIPT_DIR=`cd ${0%/*} && pwd`
-ERL={{erl}}
-IEX={{bindir}}/iex
-EPMD={{epmd}}
-INSTALLUSER={{installuser}}
-ERL_LIBS={{libdir}}
+SCRIPT_DIR=$(cd "${0%/*}" && pwd)
+ERL="{{erl}}"
+IEX="{{bindir}}/iex"
+EPMD="{{epmd}}"
+INSTALLUSER="{{installuser}}"
-# check the proper system user is used if defined
-if [ "$INSTALLUSER" != "" ] ; then
- EXEC_CMD="false"
- for GID in `id -G`; do
- if [ $GID -eq 0 ] ; then
- INSTALLUSER_HOME=$(getent passwd "$INSTALLUSER" | cut -d: -f6)
- if [ -n "$INSTALLUSER_HOME" ] && [ ! -d "$INSTALLUSER_HOME" ] ; then
- mkdir -p "$INSTALLUSER_HOME"
- chown "$INSTALLUSER" "$INSTALLUSER_HOME"
- fi
- EXEC_CMD="su $INSTALLUSER -c"
+# check the proper system user is used
+case $(id -un) in
+ "$INSTALLUSER")
+ EXEC_CMD="as_current_user"
+ ;;
+ root)
+ if [ -n "$INSTALLUSER" ] ; then
+ EXEC_CMD="as_install_user"
+ else
+ EXEC_CMD="as_current_user"
+ echo "WARNING: It is not recommended to run ejabberd as root" >&2
fi
- done
- if [ `id -g` -eq `id -g $INSTALLUSER` ] ; then
- EXEC_CMD="bash -c"
- fi
- if [ "$EXEC_CMD" = "false" ] ; then
- echo "This command can only be run by root or the user $INSTALLUSER" >&2
- exit 4
- fi
-else
- EXEC_CMD="bash -c"
-fi
+ ;;
+ *)
+ if [ -n "$INSTALLUSER" ] ; then
+ echo "ERROR: This command can only be run by root or the user $INSTALLUSER" >&2
+ exit 7
+ else
+ EXEC_CMD="as_current_user"
+ fi
+ ;;
+esac
# parse command line parameters
-declare -a ARGS=()
-while [ $# -ne 0 ] ; do
- PARAM="$1"
- shift
- case $PARAM in
- --) break ;;
- --no-timeout) EJABBERD_NO_TIMEOUT="--no-timeout" ;;
- --node) ERLANG_NODE_ARG=$1 ; shift ;;
- --config-dir) ETC_DIR="$1" ; shift ;;
- --config) EJABBERD_CONFIG_PATH="$1" ; shift ;;
- --ctl-config) EJABBERDCTL_CONFIG_PATH="$1" ; shift ;;
- --logs) LOGS_DIR="$1" ; shift ;;
- --spool) SPOOL_DIR="$1" ; shift ;;
- *) ARGS=("${ARGS[@]}" "$PARAM") ;;
+while [ $# -gt 0 ]; do
+ case $1 in
+ -n|--node) ERLANG_NODE_ARG=$2; shift 2;;
+ -s|--spool) SPOOL_DIR=$2; shift 2;;
+ -l|--logs) LOGS_DIR=$2; shift 2;;
+ -f|--config) EJABBERD_CONFIG_PATH=$2; shift 2;;
+ -c|--ctl-config) EJABBERDCTL_CONFIG_PATH=$2; shift 2;;
+ -d|--config-dir) ETC_DIR=$2; shift 2;;
+ -t|--no-timeout) NO_TIMEOUT="--no-timeout"; shift;;
+ *) break;;
esac
done
-# Define ejabberd variable if they have not been defined from the command line
-if [ "$ETC_DIR" = "" ] ; then
- ETC_DIR={{sysconfdir}}/ejabberd
-fi
-if [ "$EJABBERDCTL_CONFIG_PATH" = "" ] ; then
- EJABBERDCTL_CONFIG_PATH=$ETC_DIR/ejabberdctl.cfg
-fi
-if [ -f "$EJABBERDCTL_CONFIG_PATH" ] ; then
- . "$EJABBERDCTL_CONFIG_PATH"
-fi
-if [ "$EJABBERD_CONFIG_PATH" = "" ] ; then
- EJABBERD_CONFIG_PATH=$ETC_DIR/ejabberd.yml
-fi
-if [ "$LOGS_DIR" = "" ] ; then
- LOGS_DIR={{localstatedir}}/log/ejabberd
-fi
-if [ "$SPOOL_DIR" = "" ] ; then
- SPOOL_DIR={{localstatedir}}/lib/ejabberd
-fi
-if [ "$EJABBERD_DOC_PATH" = "" ] ; then
- EJABBERD_DOC_PATH={{docdir}}
-fi
-if [ "$ERLANG_NODE_ARG" != "" ] ; then
- ERLANG_NODE=$ERLANG_NODE_ARG
-fi
-if [ "{{release}}" != "true" -a "$EJABBERD_BIN_PATH" = "" ] ; then
- EJABBERD_BIN_PATH={{libdir}}/ejabberd/priv/bin
-fi
-EJABBERD_LOG_PATH=$LOGS_DIR/ejabberd.log
-DATETIME=`date "+%Y%m%d-%H%M%S"`
-ERL_CRASH_DUMP=$LOGS_DIR/erl_crash_$DATETIME.dump
-ERL_INETRC=$ETC_DIR/inetrc
+# define ejabberd variables if not already defined from the command line
+: "${ETC_DIR:="{{sysconfdir}}/ejabberd"}"
+: "${LOGS_DIR:="{{localstatedir}}/log/ejabberd"}"
+: "${SPOOL_DIR:="{{localstatedir}}/lib/ejabberd"}"
+: "${EJABBERD_CONFIG_PATH:="$ETC_DIR/ejabberd.yml"}"
+: "${EJABBERDCTL_CONFIG_PATH:="$ETC_DIR/ejabberdctl.cfg"}"
+[ -f "$EJABBERDCTL_CONFIG_PATH" ] && . "$EJABBERDCTL_CONFIG_PATH"
+[ -n "$ERLANG_NODE_ARG" ] && ERLANG_NODE="$ERLANG_NODE_ARG"
+[ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] && S="-s"
+: "${EJABBERD_DOC_PATH:="{{docdir}}"}"
+: "${EJABBERD_LOG_PATH:="$LOGS_DIR/ejabberd.log"}"
-# define mnesia options
-MNESIA_OPTS="-mnesia dir \"\\\"$SPOOL_DIR\\\"\" $MNESIA_OPTIONS"
# define erl parameters
ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES $ERL_OPTIONS"
-KERNEL_OPTS=""
-if [ "$FIREWALL_WINDOW" != "" ] ; then
- KERNEL_OPTS="${KERNEL_OPTS} -kernel inet_dist_listen_min ${FIREWALL_WINDOW%-*} inet_dist_listen_max ${FIREWALL_WINDOW#*-}"
+if [ -n "$FIREWALL_WINDOW" ] ; then
+ ERLANG_OPTS="$ERLANG_OPTS -kernel inet_dist_listen_min ${FIREWALL_WINDOW%-*} inet_dist_listen_max ${FIREWALL_WINDOW#*-}"
fi
-if [ "$INET_DIST_INTERFACE" != "" ] ; then
- INET_DIST_INTERFACE2="$(echo $INET_DIST_INTERFACE | sed 's/\./,/g')"
- if [ "$INET_DIST_INTERFACE" != "$INET_DIST_INTERFACE2" ] ; then
- INET_DIST_INTERFACE2="{$INET_DIST_INTERFACE2}"
+if [ -n "$INET_DIST_INTERFACE" ] ; then
+ INET_DIST_INTERFACE2=$("$ERL" -noshell -eval 'case inet:parse_address("'$INET_DIST_INTERFACE'") of {ok,IP} -> io:format("~p",[IP]); _ -> ok end.' -s erlang halt)
+ if [ -n "$INET_DIST_INTERFACE2" ] ; then
+ ERLANG_OPTS="$ERLANG_OPTS -kernel inet_dist_use_interface $INET_DIST_INTERFACE2"
fi
- KERNEL_OPTS="${KERNEL_OPTS} -kernel inet_dist_use_interface \"${INET_DIST_INTERFACE2}\""
-fi
-if [ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] ; then
- NAME="-sname"
-else
- NAME="-name"
-fi
-IEXNAME="-$NAME"
-
-# define ejabberd environment parameters
-if [ "$EJABBERD_CONFIG_PATH" != "${EJABBERD_CONFIG_PATH%.yml}" ] ; then
- rate=$(sed '/^[ ]*log_rate_limit/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH)
- rotate=$(sed '/^[ ]*log_rotate_size/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH)
- count=$(sed '/^[ ]*log_rotate_count/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH)
- date=$(sed '/^[ ]*log_rotate_date/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH)
-else
- rate=$(sed '/^[ ]*log_rate_limit/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
- rotate=$(sed '/^[ ]*log_rotate_size/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
- count=$(sed '/^[ ]*log_rotate_count/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
- date=$(sed '/^[ ]*log_rotate_date/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
fi
-[ -z "$rate" ] || EJABBERD_OPTS="log_rate_limit $rate"
-[ -z "$rotate" ] || EJABBERD_OPTS="${EJABBERD_OPTS} log_rotate_size $rotate"
-[ -z "$count" ] || EJABBERD_OPTS="${EJABBERD_OPTS} log_rotate_count $count"
-[ -z "$date" ] || EJABBERD_OPTS="${EJABBERD_OPTS} log_rotate_date '$date'"
-[ -z "$EJABBERD_OPTS" ] || EJABBERD_OPTS="-ejabberd ${EJABBERD_OPTS}"
+ERL_LIBS={{libdir}}
+ERL_CRASH_DUMP="$LOGS_DIR"/erl_crash_$(date "+%Y%m%d-%H%M%S").dump
+ERL_INETRC="$ETC_DIR"/inetrc
-[ -d "$SPOOL_DIR" ] || $EXEC_CMD "mkdir -p $SPOOL_DIR"
-cd "$SPOOL_DIR"
+# define ejabberd parameters
+EJABBERD_OPTS="$EJABBERD_OPTS\
+$(sed '/^log_rate_limit/!d;s/:[ \t]*\([0-9]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")\
+$(sed '/^log_rotate_size/!d;s/:[ \t]*\([0-9]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")\
+$(sed '/^log_rotate_count/!d;s/:[ \t]*\([0-9]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")\
+$(sed '/^log_rotate_date/!d;s/:[ \t]*\(.[^ ]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")"
+[ -n "$EJABBERD_OPTS" ] && EJABBERD_OPTS="-ejabberd $EJABBERD_OPTS"
+EJABBERD_OPTS="-mnesia dir \"$SPOOL_DIR\" $MNESIA_OPTIONS $EJABBERD_OPTS -s ejabberd"
# export global variables
export EJABBERD_CONFIG_PATH
export EJABBERD_LOG_PATH
-export EJABBERD_BIN_PATH
export EJABBERD_DOC_PATH
export EJABBERD_PID_PATH
export ERL_CRASH_DUMP
@@ -150,116 +104,26 @@ export CONTRIB_MODULES_PATH
export CONTRIB_MODULES_CONF_DIR
export ERL_LIBS
-shell_escape_str()
+# run command either directly or via su $INSTALLUSER
+exec_cmd()
{
- if test $# -eq 0; then
- printf '"" '
- else
- shell_escape "$@"
- fi
-}
-
-shell_escape()
-{
- local RES=()
- for i in "$@"; do
- if test -z "$i"; then
- printf '"" '
- else
- printf '%q ' "$i"
- fi
- done
-}
-
-# start server
-start()
-{
- check_start
- CMD="`shell_escape \"$ERL\" \"$NAME\" \"$ERLANG_NODE\"` \
- -noinput -detached \
- $MNESIA_OPTS \
- $KERNEL_OPTS \
- $EJABBERD_OPTS \
- -s ejabberd \
- $ERLANG_OPTS \
- `shell_escape \"${ARGS[@]}\" \"$@\"`"
- $EXEC_CMD "$CMD"
-}
-
-# attach to server
-debug()
-{
- debugwarning
- NID=$(uid debug)
- CMD="`shell_escape \"$ERL\" \"$NAME\" \"$NID\"` \
- -remsh $ERLANG_NODE \
- -hidden \
- $KERNEL_OPTS \
- $ERLANG_OPTS \
- `shell_escape \"${ARGS[@]}\" \"$@\"`"
- $EXEC_CMD "$CMD"
-}
-
-# attach to server using Elixir
-iexdebug()
-{
- debugwarning
- # Elixir shell is hidden as default
- NID=$(uid debug)
- CMD="`shell_escape \"$IEX\" \"$IEXNAME\" \"$NID\"` \
- -remsh $ERLANG_NODE \
- --erl `shell_escape \"$KERNEL_OPTS\"` \
- --erl `shell_escape \"$ERLANG_OPTS\"` \
- --erl `shell_escape \"${ARGS[@]}\"` \
- --erl `shell_escape_str \"$@\"`"
- $EXEC_CMD "ERL_PATH=\"$ERL\" $CMD"
-}
-
-# start interactive server
-live()
-{
- livewarning
- CMD="`shell_escape \"$ERL\" \"$NAME\" \"${ERLANG_NODE}\"` \
- $MNESIA_OPTS \
- $KERNEL_OPTS \
- $EJABBERD_OPTS \
- -s ejabberd \
- $ERLANG_OPTS \
- `shell_escape \"${ARGS[@]}\" \"$@\"`"
- $EXEC_CMD "$CMD"
+ case $EXEC_CMD in
+ as_install_user) su -s /bin/sh -c '"$0" "$@"' "$INSTALLUSER" -- "$@" ;;
+ as_current_user) "$@" ;;
+ esac
}
-
-# start interactive server with Elixir
-iexlive()
+exec_erl()
{
- livewarning
- echo $@
- CMD="`shell_escape \"$IEX\" \"$IEXNAME\" \"${ERLANG_NODE}\"` \
- --erl \"-mnesia dir \\\"$SPOOL_DIR\\\"\" \
- --erl \"`shell_escape \"$KERNEL_OPTS\"`\" \
- --erl \"`shell_escape \"$EJABBERD_OPTS\"`\" \
- --app ejabberd \
- --erl `shell_escape \"$ERLANG_OPTS\"` \
- --erl `shell_escape \"${ARGS[@]}\"` \
- --erl `shell_escape_str \"$@\"`"
- $EXEC_CMD "ERL_PATH=\"$ERL\" $CMD"
+ NODE=$1; shift
+ exec_cmd "$ERL" ${S:--}name "$NODE" $ERLANG_OPTS "$@"
}
-
-# start server in the foreground
-foreground()
+exec_iex()
{
- check_start
- CMD="`shell_escape \"$ERL\" \"$NAME\" \"$ERLANG_NODE\"` \
- -noinput \
- $MNESIA_OPTS \
- $KERNEL_OPTS \
- $EJABBERD_OPTS \
- -s ejabberd \
- $ERLANG_OPTS \
- `shell_escape \"${ARGS[@]}\" \"$@\"`"
- $EXEC_CMD "$CMD"
+ NODE=$1; shift
+ exec_cmd "$IEX" -${S:--}name "$NODE" --erl "$ERLANG_OPTS" "$@"
}
+# usage
debugwarning()
{
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
@@ -279,14 +143,13 @@ debugwarning()
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
echo " EJABBERD_BYPASS_WARNINGS=true"
echo "Press return to continue"
- read foo
+ read -r input
echo ""
fi
}
livewarning()
{
- check_start
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
echo "--------------------------------------------------------------------"
echo ""
@@ -303,37 +166,11 @@ livewarning()
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
echo " EJABBERD_BYPASS_WARNINGS=true"
echo "Press return to continue"
- read foo
+ read -r input
echo ""
fi
}
-etop()
-{
- NID=$(uid top)
- $EXEC_CMD "$ERL \
- $NAME $NID \
- -hidden -s etop -s erlang halt -output text -node $ERLANG_NODE"
-}
-
-ping()
-{
- [ -z "$1" ] && PEER=${ERLANG_NODE} || PEER=$1
- if [ "$PEER" = "${PEER%.*}" ] ; then
- PING_NAME="-sname"
- PING_NODE=$(hostname -s)
- else
- PING_NAME="-name"
- PING_NODE=$(hostname)
- fi
- NID=$(uid ping ${PING_NODE})
- $EXEC_CMD "$ERL \
- $PING_NAME $NID \
- -hidden $KERNEL_OPTS $ERLANG_OPTS \
- -eval 'io:format(\"~p~n\",[net_adm:ping('\"'\"'$PEER'\"'\"')])' \
- -s erlang halt -output text -noinput"
-}
-
help()
{
echo ""
@@ -355,33 +192,16 @@ help()
echo ""
}
-# common control function
-ctl()
-{
- NID=$(uid ctl)
- CMD="`shell_escape \"$ERL\" \"$NAME\" \"$NID\"` \
- -noinput -hidden $KERNEL_OPTS -s ejabberd_ctl \
- -extra `shell_escape \"$ERLANG_NODE\"` $EJABBERD_NO_TIMEOUT \
- `shell_escape \"$@\"`"
- $EXEC_CMD "$CMD"
- result=$?
- case $result in
- 2) help;;
- 3) help;;
- *) :;;
- esac
- return $result
-}
-
+# dynamic node name helper
uid()
{
uuid=$(uuidgen 2>/dev/null)
- [ -z "$uuid" -a -f /proc/sys/kernel/random/uuid ] && uuid=$(</proc/sys/kernel/random/uuid)
- [ -z "$uuid" ] && uuid=$(printf "%X" $RANDOM$(date +%M%S)$$)
+ [ -z "$uuid" ] && [ -f /proc/sys/kernel/random/uuid ] && uuid=$(cat /proc/sys/kernel/random/uuid)
+ [ -z "$uuid" ] && uuid=$(printf "%X" "${RANDOM:-$$}$(date +%M%S)")
uuid=${uuid%%-*}
- [ $# -eq 0 ] && echo ${uuid}-${ERLANG_NODE}
- [ $# -eq 1 ] && echo ${uuid}-${1}-${ERLANG_NODE}
- [ $# -eq 2 ] && echo ${uuid}-${1}@${2}
+ [ $# -eq 0 ] && echo "${uuid}-${ERLANG_NODE}"
+ [ $# -eq 1 ] && echo "${uuid}-${1}-${ERLANG_NODE}"
+ [ $# -eq 2 ] && echo "${uuid}-${1}@${2}"
}
# stop epmd if there is no other running node
@@ -391,56 +211,104 @@ stop_epmd()
}
# make sure node not already running and node name unregistered
+# if all ok, ensure runtime directory exists and make it current directory
check_start()
{
"$EPMD" -names 2>/dev/null | grep -q " ${ERLANG_NODE%@*} " && {
- ps ux | grep -v grep | grep -q " $ERLANG_NODE " && {
+ pgrep -f "$ERLANG_NODE" >/dev/null && {
echo "ERROR: The ejabberd node '$ERLANG_NODE' is already running."
exit 4
- } || {
- ps ux | grep -v grep | grep -q beam && {
- echo "ERROR: The ejabberd node '$ERLANG_NODE' is registered,"
- echo " but no related beam process has been found."
- echo "Shutdown all other erlang nodes, and call 'epmd -kill'."
- exit 5
- } || {
- "$EPMD" -kill >/dev/null
- }
}
+ pgrep beam >/dev/null && {
+ echo "ERROR: The ejabberd node '$ERLANG_NODE' is registered,"
+ echo " but no related beam process has been found."
+ echo "Shutdown all other erlang nodes, and call 'epmd -kill'."
+ exit 5
+ }
+ "$EPMD" -kill >/dev/null
}
}
# allow sync calls
-wait_for_status()
+wait_status()
{
# args: status try delay
# return: 0 OK, 1 KO
- timeout=$2
+ timeout="$2"
status=4
- while [ $status -ne $1 ] ; do
- sleep $3
- timeout=`expr $timeout - 1`
- [ $timeout -eq 0 ] && {
- status=$1
- } || {
- ctl status > /dev/null
- status=$?
- }
+ while [ "$status" -ne "$1" ] ; do
+ sleep "$3"
+ timeout=$((timeout - 1))
+ if [ $timeout -eq 0 ] ; then
+ status="$1"
+ else
+ exec_erl "$(uid ctl)" -hidden -noinput -s ejabberd_ctl \
+ -extra "$ERLANG_NODE" $NO_TIMEOUT status > /dev/null
+ status="$?"
+ fi
done
- [ $timeout -eq 0 ] && return 1 || return 0
+ [ $timeout -gt 0 ]
+}
+
+# ensure we can change current directory to SPOOL_DIR
+[ -d "$SPOOL_DIR" ] || exec_cmd mkdir -p "$SPOOL_DIR"
+cd "$SPOOL_DIR" || {
+ echo "ERROR: can not access directory $SPOOL_DIR"
+ exit 6
}
-# main handler
-case "${ARGS[0]}" in
- 'start') start;;
- 'debug') debug;;
- 'iexdebug') iexdebug;;
- 'live') live;;
- 'iexlive') iexlive;;
- 'foreground') foreground;;
- 'ping'*) ping ${ARGS[1]};;
- 'etop') etop;;
- 'started') wait_for_status 0 30 2;; # wait 30x2s before timeout
- 'stopped') wait_for_status 3 30 2 && stop_epmd;; # wait 30x2s before timeout
- *) ctl "${ARGS[@]}";;
+# main
+case $1 in
+ start)
+ check_start
+ exec_erl "$ERLANG_NODE" $EJABBERD_OPTS -detached
+ ;;
+ foreground)
+ check_start
+ exec_erl "$ERLANG_NODE" $EJABBERD_OPTS -noinput
+ ;;
+ live)
+ livewarning
+ check_start
+ exec_erl "$ERLANG_NODE" $EJABBERD_OPTS
+ ;;
+ debug)
+ debugwarning
+ exec_erl "$(uid debug)" -hidden -remsh "$ERLANG_NODE"
+ ;;
+ etop)
+ exec_erl "$(uid top)" -hidden -node "$ERLANG_NODE" -s etop \
+ -s erlang halt -output text
+ ;;
+ iexdebug)
+ debugwarning
+ exec_iex "$(uid debug)" --remsh "$ERLANG_NODE"
+ ;;
+ iexlive)
+ livewarning
+ exec_iex "$ERLANG_NODE" --erl "$EJABBERD_OPTS" --app ejabberd
+ ;;
+ ping)
+ PEER=${2:-$ERLANG_NODE}
+ [ "$PEER" = "${PEER%.*}" ] && PS="-s"
+ exec_cmd "$ERL" ${PS:--}name "$(uid ping "$(hostname $PS)")" $ERLANG_OPTS \
+ -noinput -hidden -eval 'io:format("~p~n",[net_adm:ping('"'$PEER'"')])' \
+ -s erlang halt -output text
+ ;;
+ started)
+ wait_status 0 30 2 # wait 30x2s before timeout
+ ;;
+ stopped)
+ wait_status 3 30 2 && stop_epmd # wait 30x2s before timeout
+ ;;
+ *)
+ exec_erl "$(uid ctl)" -hidden -noinput -s ejabberd_ctl \
+ -extra "$ERLANG_NODE" $NO_TIMEOUT "$@"
+ result=$?
+ case $result in
+ 2|3) help;;
+ *) :;;
+ esac
+ exit $result
+ ;;
esac